RsaUtils.java 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. package com.fdkankan.manage.util;
  2. import org.springframework.util.Base64Utils;
  3. import javax.crypto.BadPaddingException;
  4. import javax.crypto.Cipher;
  5. import javax.crypto.IllegalBlockSizeException;
  6. import java.io.ByteArrayOutputStream;
  7. import java.io.IOException;
  8. import java.security.*;
  9. import java.security.interfaces.RSAPrivateKey;
  10. import java.security.interfaces.RSAPublicKey;
  11. import java.security.spec.InvalidKeySpecException;
  12. import java.security.spec.PKCS8EncodedKeySpec;
  13. import java.security.spec.X509EncodedKeySpec;
  14. import java.util.Base64;
  15. public class RsaUtils {
  16. static final Base64.Decoder decoder = Base64.getDecoder();
  17. static final Base64.Encoder encoder = Base64.getEncoder();
  18. public static final String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAN0S3kQo86riY8pciZGicBOFSrdXFSP7fPNrFdmjEGbR3MKsce4e5+Mx+3/qDoVvPKd08DdbIAsXNwr8BdFU8KsCAwEAAQ==";
  19. public static final String privateKey = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEA3RLeRCjzquJjylyJkaJwE4VKt1cVI/t882sV2aMQZtHcwqxx7h7n4zH7f+oOhW88p3TwN1sgCxc3CvwF0VTwqwIDAQABAkBvzpAc1r1Niou/l4d34ThflwUPrnohpZovHdSCKocsCDy9aChZeh89Q/SL0fqIij2UWMbPBFITZA49ah3AyenZAiEA8aZQPNe7b0rgcSD53TI/Ekf8HTp5EnDgCakchvAU7B8CIQDqM7+HC7nugkAl+Rcd+SXQnqYJgrWiPv2Zs+UzvMIp9QIgGTh6d18suNjfw+7lJSjxXD8XGRXZPQt61odH6u1zwZECIQDHbl924P5oYpO7gjw0MtgHqUEcMij3Swpq2yye/OqeDQIgApfZgecc40Gj29TiKouBC1+OfLs2Kj+6IfSmsxbMA3I=";
  20. /**
  21. * RSA密钥长度必须是64的倍数,在512~65536之间。默认是1024
  22. */
  23. public static final int KEY_SIZE = 512;
  24. public static void main(String[] args) {
  25. RsaUtils rsa = new RsaUtils();
  26. KeyPairInfo keyPair = getKeyPair();
  27. //String publicKey = keyPair.getPublicKey();
  28. //String privateKey = keyPair.getPrivateKey();
  29. System.out.println("公钥:"+publicKey);
  30. System.out.println("私钥:"+privateKey);
  31. String ciphertext = rsa.encipher("MS3110218L41-448896", publicKey);
  32. System.out.println(String.format("密文:"+ciphertext));
  33. String deTxt = rsa.decipher(ciphertext, privateKey);
  34. System.out.println(deTxt);
  35. }
  36. /**
  37. * 生成公钥、私钥对(keysize=1024)
  38. */
  39. public static KeyPairInfo getKeyPair() {
  40. return getKeyPair(KEY_SIZE);
  41. }
  42. /**
  43. * 生成公钥、私钥对
  44. *
  45. * @param keySize
  46. * @return
  47. */
  48. public static KeyPairInfo getKeyPair(int keySize) {
  49. try {
  50. KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
  51. keyPairGen.initialize(keySize);
  52. // 生成一个密钥对,保存在keyPair中
  53. KeyPair keyPair = keyPairGen.generateKeyPair();
  54. // 得到私钥
  55. RSAPrivateKey oraprivateKey = (RSAPrivateKey) keyPair.getPrivate();
  56. // 得到公钥
  57. RSAPublicKey orapublicKey = (RSAPublicKey) keyPair.getPublic();
  58. KeyPairInfo pairInfo = new KeyPairInfo(keySize);
  59. // 公钥
  60. byte[] publicKeybyte = orapublicKey.getEncoded();
  61. String publicKeyString = encoder.encodeToString(publicKeybyte);
  62. pairInfo.setPublicKey(publicKeyString);
  63. // 私钥
  64. byte[] privateKeybyte = oraprivateKey.getEncoded();
  65. String privateKeyString = encoder.encodeToString(privateKeybyte);
  66. pairInfo.setPrivateKey(privateKeyString);
  67. return pairInfo;
  68. } catch (Exception e) {
  69. e.printStackTrace();
  70. return null;
  71. }
  72. }
  73. /**
  74. * 获取公钥对象
  75. *
  76. * @param publicKeyBase64
  77. * @return
  78. * @throws InvalidKeySpecException
  79. * @throws NoSuchAlgorithmException
  80. */
  81. public static PublicKey getPublicKey(String publicKeyBase64) throws InvalidKeySpecException, NoSuchAlgorithmException {
  82. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  83. X509EncodedKeySpec publicpkcs8KeySpec = new X509EncodedKeySpec(decoder.decode(publicKeyBase64));
  84. PublicKey publicKey = keyFactory.generatePublic(publicpkcs8KeySpec);
  85. return publicKey;
  86. }
  87. /**
  88. * 获取私钥对象
  89. *
  90. * @param privateKeyBase64
  91. * @return
  92. * @throws NoSuchAlgorithmException
  93. * @throws InvalidKeySpecException
  94. */
  95. public static PrivateKey getPrivateKey(String privateKeyBase64) throws NoSuchAlgorithmException, InvalidKeySpecException {
  96. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  97. PKCS8EncodedKeySpec privatekcs8KeySpec = new PKCS8EncodedKeySpec(decoder.decode(privateKeyBase64));
  98. PrivateKey privateKey = keyFactory.generatePrivate(privatekcs8KeySpec);
  99. return privateKey;
  100. }
  101. /**
  102. * 使用工钥加密
  103. *
  104. * @param content 待加密内容
  105. * @param publicKeyBase64 公钥 base64 编码
  106. * @return 经过 base64 编码后的字符串
  107. */
  108. public static String encipher(String content, String publicKeyBase64) {
  109. return encipher(content, publicKeyBase64, KEY_SIZE / 8 - 11);
  110. }
  111. /**
  112. * 使用公司钥加密(分段加密)
  113. *
  114. * @param content 待加密内容
  115. * @param publicKeyBase64 公钥 base64 编码
  116. * @param segmentSize 分段大小,一般小于 keySize/8(段小于等于0时,将不使用分段加密)
  117. * @return 经过 base64 编码后的字符串
  118. */
  119. public static String encipher(String content, String publicKeyBase64, int segmentSize) {
  120. try {
  121. PublicKey publicKey = getPublicKey(publicKeyBase64);
  122. return encipher(content, publicKey, segmentSize);
  123. } catch (Exception e) {
  124. e.printStackTrace();
  125. return null;
  126. }
  127. }
  128. /**
  129. * 分段加密
  130. *
  131. * @param ciphertext 密文
  132. * @param key 加密秘钥
  133. * @param segmentSize 分段大小,<=0 不分段
  134. * @return
  135. */
  136. public static String encipher(String ciphertext, Key key, int segmentSize) {
  137. try {
  138. // 用公钥加密
  139. byte[] srcBytes = ciphertext.getBytes();
  140. // Cipher负责完成加密或解密工作,基于RSA
  141. Cipher cipher = Cipher.getInstance("RSA");
  142. // 根据公钥,对Cipher对象进行初始化
  143. cipher.init(Cipher.ENCRYPT_MODE, key);
  144. byte[] resultBytes = null;
  145. if (segmentSize > 0)
  146. resultBytes = cipherDoFinal(cipher, srcBytes, segmentSize); // 分段加密
  147. else
  148. resultBytes = cipher.doFinal(srcBytes);
  149. String base64Str = Base64Utils.encodeToString(resultBytes);
  150. return base64Str;
  151. } catch (Exception e) {
  152. e.printStackTrace();
  153. return null;
  154. }
  155. }
  156. /**
  157. * 分段大小
  158. *
  159. * @param cipher
  160. * @param srcBytes
  161. * @param segmentSize
  162. * @return
  163. * @throws IllegalBlockSizeException
  164. * @throws BadPaddingException
  165. * @throws IOException
  166. */
  167. public static byte[] cipherDoFinal(Cipher cipher, byte[] srcBytes, int segmentSize) throws IllegalBlockSizeException, BadPaddingException, IOException {
  168. if (segmentSize <= 0)
  169. throw new RuntimeException("分段大小必须大于0");
  170. ByteArrayOutputStream out = new ByteArrayOutputStream();
  171. int inputLen = srcBytes.length;
  172. int offSet = 0;
  173. byte[] cache;
  174. int i = 0;
  175. // 对数据分段解密
  176. while (inputLen - offSet > 0) {
  177. if (inputLen - offSet > segmentSize) {
  178. cache = cipher.doFinal(srcBytes, offSet, segmentSize);
  179. } else {
  180. cache = cipher.doFinal(srcBytes, offSet, inputLen - offSet);
  181. }
  182. out.write(cache, 0, cache.length);
  183. i++;
  184. offSet = i * segmentSize;
  185. }
  186. byte[] data = out.toByteArray();
  187. out.close();
  188. return data;
  189. }
  190. /**
  191. * 使用私钥解密
  192. *
  193. * @param contentBase64 待加密内容,base64 编码
  194. * @param privateKeyBase64 私钥 base64 编码
  195. * @return
  196. * @segmentSize 分段大小
  197. */
  198. public static String decipher(String contentBase64, String privateKeyBase64) {
  199. return decipher(contentBase64, privateKeyBase64, KEY_SIZE / 8);
  200. }
  201. /**
  202. * 使用私钥解密(分段解密)
  203. *
  204. * @param contentBase64 待加密内容,base64 编码
  205. * @param privateKeyBase64 私钥 base64 编码
  206. * @return
  207. * @segmentSize 分段大小
  208. */
  209. public static String decipher(String contentBase64, String privateKeyBase64, int segmentSize) {
  210. try {
  211. PrivateKey privateKey = getPrivateKey(privateKeyBase64);
  212. return decipher(contentBase64, privateKey, segmentSize);
  213. } catch (Exception e) {
  214. e.printStackTrace();
  215. return null;
  216. }
  217. }
  218. /**
  219. * 分段解密
  220. *
  221. * @param contentBase64 密文
  222. * @param key 解密秘钥
  223. * @param segmentSize 分段大小(小于等于0不分段)
  224. * @return
  225. */
  226. public static String decipher(String contentBase64, Key key, int segmentSize) {
  227. try {
  228. // 用私钥解密
  229. byte[] srcBytes = Base64Utils.decodeFromString(contentBase64);
  230. // Cipher负责完成加密或解密工作,基于RSA
  231. Cipher deCipher = Cipher.getInstance("RSA");
  232. // 根据公钥,对Cipher对象进行初始化
  233. deCipher.init(Cipher.DECRYPT_MODE, key);
  234. byte[] decBytes = null;// deCipher.doFinal(srcBytes);
  235. if (segmentSize > 0)
  236. decBytes = cipherDoFinal(deCipher, srcBytes, segmentSize); // 分段加密
  237. else
  238. decBytes = deCipher.doFinal(srcBytes);
  239. String decrytStr = new String(decBytes);
  240. return decrytStr;
  241. } catch (Exception e) {
  242. e.printStackTrace();
  243. return null;
  244. }
  245. }
  246. /**
  247. * 秘钥对
  248. */
  249. public static class KeyPairInfo {
  250. String privateKey;
  251. String publicKey;
  252. int keySize = 0;
  253. public KeyPairInfo(int keySize) {
  254. setKeySize(keySize);
  255. }
  256. public KeyPairInfo(String publicKey, String privateKey) {
  257. setPrivateKey(privateKey);
  258. setPublicKey(publicKey);
  259. }
  260. public String getPrivateKey() {
  261. return privateKey;
  262. }
  263. public void setPrivateKey(String privateKey) {
  264. this.privateKey = privateKey;
  265. }
  266. public String getPublicKey() {
  267. return publicKey;
  268. }
  269. public void setPublicKey(String publicKey) {
  270. this.publicKey = publicKey;
  271. }
  272. public int getKeySize() {
  273. return keySize;
  274. }
  275. public void setKeySize(int keySize) {
  276. this.keySize = keySize;
  277. }
  278. }
  279. }