|
7 | 7 | import java.io.IOException;
|
8 | 8 | import java.security.DigestInputStream;
|
9 | 9 | import java.security.InvalidKeyException;
|
| 10 | +import java.security.Key; |
| 11 | +import java.security.KeyFactory; |
10 | 12 | import java.security.MessageDigest;
|
11 | 13 | import java.security.NoSuchAlgorithmException;
|
12 | 14 | import java.security.spec.AlgorithmParameterSpec;
|
| 15 | +import java.security.spec.InvalidKeySpecException; |
| 16 | +import java.security.spec.PKCS8EncodedKeySpec; |
| 17 | +import java.security.spec.X509EncodedKeySpec; |
13 | 18 |
|
| 19 | +import javax.crypto.BadPaddingException; |
14 | 20 | import javax.crypto.Cipher;
|
| 21 | +import javax.crypto.IllegalBlockSizeException; |
15 | 22 | import javax.crypto.Mac;
|
| 23 | +import javax.crypto.NoSuchPaddingException; |
16 | 24 | import javax.crypto.spec.IvParameterSpec;
|
17 | 25 | import javax.crypto.spec.SecretKeySpec;
|
18 | 26 |
|
@@ -925,6 +933,181 @@ private static byte[] symmetricTemplate(final byte[] data,
|
925 | 933 | }
|
926 | 934 | }
|
927 | 935 |
|
| 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 | + |
928 | 1111 | private static final char HEX_DIGITS[] =
|
929 | 1112 | {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
930 | 1113 |
|
|
0 commit comments