Skip to content

Commit b45808d

Browse files
committed
see 04/22 log
1 parent 84d515f commit b45808d

File tree

6 files changed

+237
-15
lines changed

6 files changed

+237
-15
lines changed

app/src/main/java/com/blankj/androidutilcode/feature/core/span/SpanActivity.java

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ public void updateDrawState(TextPaint ds) {
109109
initAnimSpan();
110110
startAnim();
111111

112+
112113
tvAboutSpan.setText(new SpanUtils()
113114
.appendLine("SpanUtils").setBackgroundColor(Color.LTGRAY).setBold().setForegroundColor(Color.YELLOW).setAlign(Layout.Alignment.ALIGN_CENTER)
114115
.appendLine("前景色").setForegroundColor(Color.GREEN)

utilcode/README-CN.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ encrypt3DES, encrypt3DES2HexString, encrypt3DES2Base64: 3DES 加密
202202
decrypt3DES, decryptHexString3DES, decryptBase64_3DES : 3DES 解密
203203
encryptAES, encryptAES2HexString, encryptAES2Base64 : AES 加密
204204
decryptAES, decryptHexStringAES, decryptBase64AES : AES 解密
205+
encryptRSA, encryptRSA2HexString, encryptRSA2Base64 : RSA 加密
206+
decryptRSA, decryptHexStringRSA, decryptBase64RSA : RSA 解密
205207
```
206208

207209
* ### 文件相关 -> [FileIOUtils.java][fileio.java] -> [Test][fileio.test]
@@ -654,7 +656,7 @@ showCustomLong : 显示长时自定义吐司
654656
cancel : 取消吐司显示
655657
```
656658

657-
* ### Uri 相关 -> [UriUtils.java][uri.java]
659+
* ### URI 相关 -> [UriUtils.java][uri.java]
658660
```
659661
getUriForFile: 获取文件 URI
660662
```

utilcode/src/main/java/com/blankj/utilcode/util/EncryptUtils.java

+183
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,20 @@
77
import java.io.IOException;
88
import java.security.DigestInputStream;
99
import java.security.InvalidKeyException;
10+
import java.security.Key;
11+
import java.security.KeyFactory;
1012
import java.security.MessageDigest;
1113
import java.security.NoSuchAlgorithmException;
1214
import java.security.spec.AlgorithmParameterSpec;
15+
import java.security.spec.InvalidKeySpecException;
16+
import java.security.spec.PKCS8EncodedKeySpec;
17+
import java.security.spec.X509EncodedKeySpec;
1318

19+
import javax.crypto.BadPaddingException;
1420
import javax.crypto.Cipher;
21+
import javax.crypto.IllegalBlockSizeException;
1522
import javax.crypto.Mac;
23+
import javax.crypto.NoSuchPaddingException;
1624
import javax.crypto.spec.IvParameterSpec;
1725
import javax.crypto.spec.SecretKeySpec;
1826

@@ -925,6 +933,181 @@ private static byte[] symmetricTemplate(final byte[] data,
925933
}
926934
}
927935

936+
///////////////////////////////////////////////////////////////////////////
937+
// RSA encryption
938+
///////////////////////////////////////////////////////////////////////////
939+
940+
/**
941+
* Return the Base64-encode bytes of RSA encryption.
942+
*
943+
* @param data The data.
944+
* @param key The key.
945+
* @param isPublicKey True to use public key, false to use private key.
946+
* @param transformation The name of the transformation, e.g., <i>RSA/CBC/PKCS1Padding</i>.
947+
* @return the Base64-encode bytes of RSA encryption
948+
*/
949+
public static byte[] encryptRSA2Base64(final byte[] data,
950+
final byte[] key,
951+
final boolean isPublicKey,
952+
final String transformation) {
953+
return base64Encode(encryptRSA(data, key, isPublicKey, transformation));
954+
}
955+
956+
/**
957+
* Return the hex string of RSA encryption.
958+
*
959+
* @param data The data.
960+
* @param key The key.
961+
* @param isPublicKey True to use public key, false to use private key.
962+
* @param transformation The name of the transformation, e.g., <i>RSA/CBC/PKCS1Padding</i>.
963+
* @return the hex string of RSA encryption
964+
*/
965+
public static String encryptRSA2HexString(final byte[] data,
966+
final byte[] key,
967+
final boolean isPublicKey,
968+
final String transformation) {
969+
return bytes2HexString(encryptRSA(data, key, isPublicKey, transformation));
970+
}
971+
972+
/**
973+
* Return the bytes of RSA encryption.
974+
*
975+
* @param data The data.
976+
* @param key The key.
977+
* @param isPublicKey True to use public key, false to use private key.
978+
* @param transformation The name of the transformation, e.g., <i>RSA/CBC/PKCS1Padding</i>.
979+
* @return the bytes of RSA encryption
980+
*/
981+
public static byte[] encryptRSA(final byte[] data,
982+
final byte[] key,
983+
final boolean isPublicKey,
984+
final String transformation) {
985+
return rsaTemplate(data, key, isPublicKey, transformation, true);
986+
}
987+
988+
/**
989+
* Return the bytes of RSA decryption for Base64-encode bytes.
990+
*
991+
* @param data The data.
992+
* @param key The key.
993+
* @param isPublicKey True to use public key, false to use private key.
994+
* @param transformation The name of the transformation, e.g., <i>RSA/CBC/PKCS1Padding</i>.
995+
* @return the bytes of RSA decryption for Base64-encode bytes
996+
*/
997+
public static byte[] decryptBase64RSA(final byte[] data,
998+
final byte[] key,
999+
final boolean isPublicKey,
1000+
final String transformation) {
1001+
return decryptRSA(base64Decode(data), key, isPublicKey, transformation);
1002+
}
1003+
1004+
/**
1005+
* Return the bytes of RSA decryption for hex string.
1006+
*
1007+
* @param data The data.
1008+
* @param key The key.
1009+
* @param isPublicKey True to use public key, false to use private key.
1010+
* @param transformation The name of the transformation, e.g., <i>RSA/CBC/PKCS1Padding</i>.
1011+
* @return the bytes of RSA decryption for hex string
1012+
*/
1013+
public static byte[] decryptHexStringRSA(final String data,
1014+
final byte[] key,
1015+
final boolean isPublicKey,
1016+
final String transformation) {
1017+
return decryptRSA(hexString2Bytes(data), key, isPublicKey, transformation);
1018+
}
1019+
1020+
/**
1021+
* Return the bytes of RSA decryption.
1022+
*
1023+
* @param data The data.
1024+
* @param key The key.
1025+
* @param isPublicKey True to use public key, false to use private key.
1026+
* @param transformation The name of the transformation, e.g., <i>RSA/CBC/PKCS1Padding</i>.
1027+
* @return the bytes of RSA decryption
1028+
*/
1029+
public static byte[] decryptRSA(final byte[] data,
1030+
final byte[] key,
1031+
final boolean isPublicKey,
1032+
final String transformation) {
1033+
return rsaTemplate(data, key, isPublicKey, transformation, false);
1034+
}
1035+
1036+
/**
1037+
* Return the bytes of RSA encryption or decryption.
1038+
*
1039+
* @param data The data.
1040+
* @param key The key.
1041+
* @param isPublicKey True to use public key, false to use private key.
1042+
* @param transformation The name of the transformation, e.g., <i>DES/CBC/PKCS1Padding</i>.
1043+
* @param isEncrypt True to encrypt, false otherwise.
1044+
* @return the bytes of RSA encryption or decryption
1045+
*/
1046+
private static byte[] rsaTemplate(final byte[] data,
1047+
final byte[] key,
1048+
final boolean isPublicKey,
1049+
final String transformation,
1050+
final boolean isEncrypt) {
1051+
if (data == null || data.length == 0 || key == null || key.length == 0) {
1052+
return null;
1053+
}
1054+
try {
1055+
Key rsaKey;
1056+
if (isPublicKey) {
1057+
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(key);
1058+
rsaKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);
1059+
} else {
1060+
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(key);
1061+
rsaKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
1062+
}
1063+
if (rsaKey == null) return null;
1064+
Cipher cipher = Cipher.getInstance(transformation);
1065+
cipher.init(isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, rsaKey);
1066+
int len = data.length;
1067+
int maxLen = isEncrypt ? 117 : 128;
1068+
int count = len / maxLen;
1069+
if (count > 0) {
1070+
byte[] ret = new byte[0];
1071+
byte[] buff = new byte[maxLen];
1072+
int index = 0;
1073+
for (int i = 0; i < count; i++) {
1074+
System.arraycopy(data, index, buff, 0, maxLen);
1075+
ret = joins(ret, cipher.doFinal(buff));
1076+
index += maxLen;
1077+
}
1078+
if (index != len) {
1079+
int restLen = len - index;
1080+
buff = new byte[restLen];
1081+
System.arraycopy(data, index, buff, 0, restLen);
1082+
ret = joins(ret, cipher.doFinal(buff));
1083+
}
1084+
return ret;
1085+
} else {
1086+
return cipher.doFinal(data);
1087+
}
1088+
} catch (NoSuchAlgorithmException e) {
1089+
e.printStackTrace();
1090+
} catch (NoSuchPaddingException e) {
1091+
e.printStackTrace();
1092+
} catch (InvalidKeyException e) {
1093+
e.printStackTrace();
1094+
} catch (BadPaddingException e) {
1095+
e.printStackTrace();
1096+
} catch (IllegalBlockSizeException e) {
1097+
e.printStackTrace();
1098+
} catch (InvalidKeySpecException e) {
1099+
e.printStackTrace();
1100+
}
1101+
return null;
1102+
}
1103+
1104+
private static byte[] joins(final byte[] prefix, final byte[] suffix) {
1105+
byte[] ret = new byte[prefix.length + suffix.length];
1106+
System.arraycopy(prefix, 0, ret, 0, prefix.length);
1107+
System.arraycopy(suffix, 0, ret, prefix.length, suffix.length);
1108+
return ret;
1109+
}
1110+
9281111
private static final char HEX_DIGITS[] =
9291112
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
9301113

utilcode/src/main/java/com/blankj/utilcode/util/IntentUtils.java

+17-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import android.content.ComponentName;
44
import android.content.Intent;
55
import android.net.Uri;
6+
import android.os.Build;
67
import android.os.Bundle;
78
import android.provider.MediaStore;
89
import android.support.annotation.RequiresPermission;
10+
import android.support.v4.content.FileProvider;
911

1012
import java.io.File;
1113

@@ -74,9 +76,15 @@ public static Intent getInstallAppIntent(final String filePath, final boolean is
7476
public static Intent getInstallAppIntent(final File file, final boolean isNewTask) {
7577
if (file == null) return null;
7678
Intent intent = new Intent(Intent.ACTION_VIEW);
77-
Uri data = UriUtils.getUriForFile(file);
78-
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
79+
Uri data;
7980
String type = "application/vnd.android.package-archive";
81+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
82+
data = Uri.fromFile(file);
83+
} else {
84+
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
85+
String authority = Utils.getApp().getPackageName() + ".utilcode.provider";
86+
data = FileProvider.getUriForFile(Utils.getApp(), authority, file);
87+
}
8088
intent.setDataAndType(data, type);
8189
return getIntent(intent, isNewTask);
8290
}
@@ -146,8 +154,14 @@ public static Intent getInstallAppIntent(final File file,
146154
final boolean isNewTask) {
147155
if (file == null) return null;
148156
Intent intent = new Intent(Intent.ACTION_VIEW);
149-
Uri data = UriUtils.getUriForFile(file);
157+
Uri data;
150158
String type = "application/vnd.android.package-archive";
159+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
160+
data = Uri.fromFile(file);
161+
} else {
162+
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
163+
data = FileProvider.getUriForFile(Utils.getApp(), authority, file);
164+
}
151165
intent.setDataAndType(data, type);
152166
return getIntent(intent, isNewTask);
153167
}

utilcode/src/main/java/com/blankj/utilcode/util/UriUtils.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* author: Blankj
1212
* blog : http://blankj.com
1313
* time : 2018/04/20
14-
* desc : uri 相关
14+
* desc : URI 相关
1515
* </pre>
1616
*/
1717
public final class UriUtils {
@@ -20,6 +20,12 @@ private UriUtils() {
2020
throw new UnsupportedOperationException("u can't instantiate me...");
2121
}
2222

23+
/**
24+
* Return a content URI for a given file.
25+
*
26+
* @param file The file.
27+
* @return a content URI for a given file
28+
*/
2329
public static Uri getUriForFile(final File file) {
2430
if (file == null) return null;
2531
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

utilcode/src/test/java/com/blankj/utilcode/util/EncryptUtilsTest.java

+26-10
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ public void encryptMD5() throws Exception {
6767
);
6868
}
6969

70+
@Test
71+
public void encryptMD5File() throws Exception {
72+
String fileMd5 = "7f138a09169b250e9dcb378140907378";
73+
assertEquals(
74+
fileMd5.toUpperCase(),
75+
EncryptUtils.encryptMD5File2String(new File(PATH_ENCRYPT + "MD5.txt"))
76+
);
77+
}
78+
7079
@Test
7180
public void encryptSHA1() throws Exception {
7281
String blankjSHA1 = "C606ACCB1FEB669E19D080ADDDDBB8E6CDA5F43C";
@@ -447,12 +456,6 @@ public void decrypt3DES() throws Exception {
447456

448457
@Test
449458
public void encryptAES() throws Exception {
450-
// EncryptUtils.encryptAES(
451-
// bytesDataAES,
452-
// bytesKeyAES,
453-
// "AES/ECB/NoPadding",
454-
// null
455-
// );
456459
assertTrue(
457460
Arrays.equals(
458461
bytesResAES,
@@ -518,12 +521,25 @@ public void decryptAES() throws Exception {
518521
);
519522
}
520523

524+
private String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCWuAuSCrzUXC1l4ixXBeBfotUtkALrAjLM5UHiVfOFHrRJHM41HSeHVm56UZHgJlwk80R8juu1ykuhkgrilTv7H+3MpZdIunvndDElgdgk8aI2Ip4GUlemUDvCtWd3ychWEh4kYQ8CeInQvNM08imoLFldvbjWt/IkGK+BcGzamQIDAQAB";
525+
private String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJa4C5IKvNRcLWXiLFcF4F+i1S2QAusCMszlQeJV84UetEkczjUdJ4dWbnpRkeAmXCTzRHyO67XKS6GSCuKVO/sf7cyll0i6e+d0MSWB2CTxojYingZSV6ZQO8K1Z3fJyFYSHiRhDwJ4idC80zTyKagsWV29uNa38iQYr4FwbNqZAgMBAAECgYAxV1k6W1eMMg0OsKeRabQVuwoNG3tJEnQtDdSu0zKg3vdohAyh6MR7EvmiA7g86HH8CsPd/y/9WJe/8j6sBO0Ye9gt7eyQ2NiwWvlTuwNmngcSTapVvVI6NEyJFMfQt9PB1EHLNAXlz8jtJUyA7C48jReQD9p/SzAP0VxG7lwyMQJBAOjE7hAZ/6fyP3DB1fG7jr9gONZcz3TUaqx6BUn4GKZnckW08ht9Xqcqft5Hthu8BbLM9ptQ0U8QZekrJwD6ya0CQQClwstZMPu8jLhsgugVwodcG1mPEOiw9Yjnmt9+WTI07Ll2uFv//hRXBnahBBnZbucUYEbUY3kqUX9b3e9TmEodAkEAybPMbxt4VDoxCy6Mi/pxChkBZ4/pHV3sSiU6bAyWn6vIc+sGWRfca5MBePA/N+1IKtY9Y/02QwL8rH5+P/URyQJAL/hdjORGFdzLimuf6pwvPBKWKncEQCHuisghIZmClBpl2duklELddAnkztg2+tvDd/wcw14+NGb9aoKhvhl2aQJAbvcgoPU+xs0CjeexH+TS2S/jKkTRpvP2CpPK/k71m13xWdE8RtMkYY1measRmlIwOfWze7ll/PGT4dxWf31FNg==";
526+
private String dataRSA = "BlankjBlankjBlankjBlankjBlankjBlankjBlankjBlankjBlankjBlankjBlankjBlankjBlankjBlankjBlankjBlankjBlankjBlankjBlankjBla12345678";
527+
521528
@Test
522-
public void encryptMD5File() throws Exception {
523-
String fileMd5 = "7f138a09169b250e9dcb378140907378";
529+
public void encryptRSA() throws Exception {
524530
assertEquals(
525-
fileMd5.toUpperCase(),
526-
EncryptUtils.encryptMD5File2String(new File(PATH_ENCRYPT + "MD5.txt"))
531+
EncryptUtils.decryptRSA(
532+
EncryptUtils.encryptRSA(
533+
dataRSA.getBytes(),
534+
EncodeUtils.base64Decode(publicKey.getBytes()),
535+
true,
536+
"RSA/ECB/PKCS1Padding"
537+
),
538+
EncodeUtils.base64Decode(privateKey.getBytes()),
539+
false,
540+
"RSA/ECB/PKCS1Padding"
541+
),
542+
dataRSA.getBytes()
527543
);
528544
}
529545
}

0 commit comments

Comments
 (0)