App下載

Java如何使用rsa非對(duì)稱(chēng)加密法進(jìn)行加密

猿友 2021-06-23 17:36:04 瀏覽數(shù) (4020)
反饋

公鑰與私鑰是成對(duì)的,一般的,我們認(rèn)為的是公鑰加密、私鑰解密、私鑰簽名、公鑰驗(yàn)證,有人說(shuō)成私鑰加密,公鑰解密時(shí)不對(duì)的。

公鑰與私鑰的生成有多種方式,可以通過(guò)程序生成(下文具體實(shí)現(xiàn)),可以通過(guò)openssl工具:  

  1. # 生成一個(gè)私鑰,推薦使用1024位的秘鑰,秘鑰以pem格式保存到-out參數(shù)指定的文件中,采用PKCS1格式
  2. openssl genrsa -out rsa.pem 1024
  3. # 生成與私鑰對(duì)應(yīng)的公鑰,生成的是Subject Public Key,一般配合PKCS8格式私鑰使用
  4. openssl rsa -in rsa.pem -pubout -out rsa.pub

RSA生成公鑰與私鑰一般有兩種格式:PKCS1和PKCS8,上面的命令生成的秘鑰是PKCS1格式的,而公鑰是Subject Public Key,一般配合PKCS8格式私鑰使用,所以就可能會(huì)涉及到PKCS1和PKCS8之間的轉(zhuǎn)換:

  1. # PKCS1格式私鑰轉(zhuǎn)換為PKCS8格式私鑰,私鑰直接輸出到-out參數(shù)指定的文件中
  2. openssl pkcs8 -topk8 -inform PEM -in rsa.pem -outform pem -nocrypt -out rsa_pkcs8.pem
  3. # PKCS8格式私鑰轉(zhuǎn)換為PKCS1格式私鑰,私鑰直接輸出到-out參數(shù)指定的文件中
  4. openssl rsa -in rsa_pkcs8.pem -out rsa_pkcs1.pem
  5.  
  6. # PKCS1格式公鑰轉(zhuǎn)換為PKCS8格式公鑰,轉(zhuǎn)換后的內(nèi)容直接輸出
  7. openssl rsa -pubin -in rsa.pub -RSAPublicKey_out
  8. # PKCS8格式公鑰轉(zhuǎn)換為PKCS1格式公鑰,轉(zhuǎn)換后的內(nèi)容直接輸出
  9. openssl rsa -RSAPublicKey_in -pubout -in rsa.pub

現(xiàn)實(shí)中,我們往往從pem、crt、pfx文件獲取公私和私鑰,crt、pfx的制作可以參考:簡(jiǎn)單的制作ssl證書(shū),并在nginx和IIS中使用。

Java實(shí)現(xiàn)

為簡(jiǎn)化說(shuō)明介紹,這里我直接封裝了一個(gè)工具類(lèi),因?yàn)橐獜膒em、crt、pfx文件獲取公私和私鑰,因此引用了一個(gè)第三方包:BouncyCastle,可以直接在pom.xml中添加依賴(lài):  

  1. <dependency>
  2. <groupId>org.bouncycastle</groupId>
  3. <artifactId>bcprov-jdk15on</artifactId>
  4. <version>1.68</version>
  5. </dependency>

簡(jiǎn)單封裝的RsaUtil.java:  

  1. import java.io.FileInputStream;
  2. import java.io.FileReader;
  3. import java.io.FileWriter;
  4. import java.math.BigInteger;
  5. import java.security.KeyFactory;
  6. import java.security.KeyPair;
  7. import java.security.KeyPairGenerator;
  8. import java.security.KeyStore;
  9. import java.security.PrivateKey;
  10. import java.security.PublicKey;
  11. import java.security.SecureRandom;
  12. import java.security.Security;
  13. import java.security.Signature;
  14. import java.security.cert.Certificate;
  15. import java.security.cert.CertificateFactory;
  16. import java.security.cert.X509Certificate;
  17. import java.security.interfaces.RSAPrivateKey;
  18. import java.security.interfaces.RSAPublicKey;
  19. import java.security.spec.KeySpec;
  20. import java.security.spec.PKCS8EncodedKeySpec;
  21. import java.security.spec.RSAPrivateCrtKeySpec;
  22. import java.security.spec.RSAPublicKeySpec;
  23. import java.security.spec.X509EncodedKeySpec;
  24. import java.util.Enumeration;
  25.  
  26. import javax.crypto.Cipher;
  27.  
  28. import org.bouncycastle.asn1.ASN1Integer;
  29. import org.bouncycastle.asn1.ASN1Primitive;
  30. import org.bouncycastle.asn1.DLSequence;
  31. import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
  32. import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
  33. import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
  34. import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
  35. import org.bouncycastle.jce.provider.BouncyCastleProvider;
  36. import org.bouncycastle.util.io.pem.PemObject;
  37. import org.bouncycastle.util.io.pem.PemReader;
  38. import org.bouncycastle.util.io.pem.PemWriter;
  39.  
  40. public class RsaUtil {
  41.  
  42. static {
  43. Security.addProvider(new BouncyCastleProvider());
  44. }
  45.  
  46. /**
  47. * 隨機(jī)生成密鑰對(duì)
  48. *
  49. * @param usePKCS8
  50. * 是否采用PKCS8填充模式
  51. */
  52. public static Object[] generateRsaKey(boolean usePKCS8) throws Exception {
  53. KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME);
  54. // 初始化
  55. keyPairGen.initialize(1024, new SecureRandom());
  56. // 生成一個(gè)密鑰對(duì),保存在keyPair中
  57. KeyPair keyPair = keyPairGen.generateKeyPair();
  58. RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私鑰
  59. RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公鑰
  60.  
  61. // 這兩個(gè)公私鑰是PKCS8格式的
  62. byte[] publicKeyBytes = publicKey.getEncoded();
  63. byte[] privateKeyBytes = privateKey.getEncoded();
  64.  
  65. if (!usePKCS8) {
  66. // 將PSCK8格式公私鑰轉(zhuǎn)換為PKCS1格式
  67. publicKeyBytes = pkcs8ToPkcs1(false, publicKeyBytes);
  68. privateKeyBytes = pkcs8ToPkcs1(true, privateKeyBytes);
  69. }
  70.  
  71. return new Object[] { publicKeyBytes, privateKeyBytes };
  72. }
  73.  
  74. /**
  75. * 從Pem文件讀取密鑰對(duì)
  76. *
  77. * @param reader
  78. * 輸入流
  79. * @param pemFileName
  80. * pem文件
  81. */
  82. public static byte[] readFromPem(String pemFileName) throws Exception {
  83. PemReader pemReader = new PemReader(new FileReader(pemFileName));
  84. PemObject pemObject = pemReader.readPemObject();
  85. byte[] publicKey = pemObject.getContent();
  86. pemReader.close();
  87. return publicKey;
  88. }
  89.  
  90. /**
  91. * 從Pem文件讀取密鑰
  92. *
  93. * @param isPrivateKey
  94. * 是否是私鑰
  95. * @param buffer
  96. * 字節(jié)
  97. * @param pemFileName
  98. * pem文件
  99. */
  100. public static void writeToPem(byte[] buffer, boolean isPrivateKey, String pemFileName) throws Exception {
  101.  
  102. PemObject pemObject = new PemObject(isPrivateKey ? "RSA PRIVATE KEY" : "RSA PUBLIC KEY", buffer);
  103. FileWriter fileWriter = new FileWriter(pemFileName);
  104. PemWriter pemWriter = new PemWriter(fileWriter);
  105. pemWriter.writeObject(pemObject);
  106. pemWriter.close();
  107. }
  108.  
  109. /**
  110. * 從crt文件讀取公鑰(pkcs8)
  111. *
  112. * @param crtFileName
  113. * crt文件
  114. * @return 公鑰
  115. */
  116. public static byte[] readPublicKeyFromCrt(String crtFileName) throws Exception {
  117. CertificateFactory cf = CertificateFactory.getInstance("X.509");
  118. X509Certificate cert = (X509Certificate) cf.generateCertificate(new FileInputStream(crtFileName));
  119.  
  120. PublicKey publicKey = cert.getPublicKey();
  121. return publicKey.getEncoded();
  122. }
  123.  
  124. /**
  125. * 從pfx文件讀取秘鑰對(duì)(pkcs8)
  126. *
  127. * @param pfxFileName
  128. * pfx文件
  129. * @return 秘鑰對(duì)
  130. */
  131. public static Object[] readFromPfx(String pfxFileName, String password) throws Exception {
  132. KeyStore keystore = KeyStore.getInstance("PKCS12");
  133. char[] passwordChars = null;
  134. if (password == null || password.equals("")) {
  135. passwordChars = null;
  136. } else {
  137. passwordChars = password.toCharArray();
  138. }
  139. keystore.load(new FileInputStream(pfxFileName), passwordChars);
  140. Enumeration<String> enums = keystore.aliases();
  141.  
  142. PrivateKey privateKey = null;
  143. Certificate certificate = null;
  144. while (enums.hasMoreElements()) {
  145. String alias = enums.nextElement();
  146. System.out.println(alias);
  147. if (keystore.isKeyEntry(alias)) {
  148. privateKey = (PrivateKey) keystore.getKey(alias, passwordChars);
  149. certificate = keystore.getCertificate(alias);
  150. }
  151. if (privateKey != null && certificate != null)
  152. break;
  153. }
  154. if (privateKey == null || certificate == null) {
  155. throw new Exception("fail to read key from pfx");
  156. }
  157.  
  158. PublicKey publicKey = certificate.getPublicKey();
  159. return new Object[] { publicKey.getEncoded(), privateKey.getEncoded() };
  160. }
  161.  
  162. /**
  163. * Pkcs8轉(zhuǎn)Pkcs1
  164. *
  165. * @param isPrivateKey
  166. * 是否是私鑰轉(zhuǎn)換
  167. * @param buffer
  168. * Pkcs1秘鑰
  169. * @return Pkcs8秘鑰
  170. * @throws Exception
  171. * 加密過(guò)程中的異常信息
  172. */
  173. public static byte[] pkcs8ToPkcs1(boolean isPrivateKey, byte[] buffer) throws Exception {
  174. if (isPrivateKey) {
  175. PrivateKeyInfo privateKeyInfo = PrivateKeyInfo.getInstance(buffer);
  176. return privateKeyInfo.parsePrivateKey().toASN1Primitive().getEncoded();
  177. } else {
  178. SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(buffer);
  179. return subjectPublicKeyInfo.parsePublicKey().toASN1Primitive().getEncoded();
  180. }
  181. }
  182.  
  183. /**
  184. * Pkcs1轉(zhuǎn)Pkcs8
  185. *
  186. * @param isPrivateKey
  187. * 是否是私鑰轉(zhuǎn)換
  188. * @param buffer
  189. * Pkcs1秘鑰
  190. * @return Pkcs8秘鑰
  191. * @throws Exception
  192. * 加密過(guò)程中的異常信息
  193. */
  194. public static byte[] pkcs1ToPkcs8(boolean isPrivateKey, byte[] buffer) throws Exception {
  195. AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption);
  196. ASN1Primitive asn1Primitive = ASN1Primitive.fromByteArray(buffer);
  197. if (isPrivateKey) {
  198. PrivateKeyInfo privateKeyInfo = new PrivateKeyInfo(algorithmIdentifier, asn1Primitive);
  199. return privateKeyInfo.getEncoded();
  200. } else {
  201. SubjectPublicKeyInfo subjectPublicKeyInfo = new SubjectPublicKeyInfo(algorithmIdentifier, asn1Primitive);
  202. return subjectPublicKeyInfo.getEncoded();
  203. }
  204. }
  205.  
  206. /**
  207. * RSA公鑰
  208. *
  209. * @param usePKCS8
  210. * 是否采用PKCS8填充模式
  211. * @param publicKey
  212. * 公鑰
  213. * @return 公鑰
  214. * @throws Exception
  215. * 加密過(guò)程中的異常信息
  216. */
  217. public static RSAPublicKey generatePublicKey(boolean usePKCS8, byte[] publicKey) throws Exception {
  218. KeySpec keySpec;
  219. if (usePKCS8) {
  220. // PKCS8填充
  221. keySpec = new X509EncodedKeySpec(publicKey);
  222. } else {
  223. // PKCS1填充
  224. DLSequence sequence = (DLSequence) ASN1Primitive.fromByteArray(publicKey);
  225. BigInteger v1 = ((ASN1Integer) sequence.getObjectAt(0)).getValue();
  226. BigInteger v2 = ((ASN1Integer) sequence.getObjectAt(1)).getValue();
  227. keySpec = new RSAPublicKeySpec(v1, v2);
  228. }
  229.  
  230. RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME).generatePublic(keySpec);
  231. return pubKey;
  232. }
  233.  
  234. /**
  235. * RSA私鑰
  236. *
  237. * @param usePKCS8
  238. * 是否采用PKCS8填充模式
  239. * @param privateKey
  240. * 私鑰
  241. * @return 私鑰
  242. * @throws Exception
  243. * 解密過(guò)程中的異常信息
  244. */
  245. public static RSAPrivateKey generatePrivateKey(boolean usePKCS8, byte[] privateKey) throws Exception {
  246. KeySpec keySpec;
  247. if (usePKCS8) {
  248. // PKCS8填充
  249. keySpec = new PKCS8EncodedKeySpec(privateKey);
  250. } else {
  251. // PKCS1填充
  252. DLSequence sequence = (DLSequence) ASN1Primitive.fromByteArray(privateKey);
  253. // BigInteger v1= ((ASN1Integer)sequence.getObjectAt(0)).getValue();
  254. BigInteger v2 = ((ASN1Integer) sequence.getObjectAt(1)).getValue();
  255. BigInteger v3 = ((ASN1Integer) sequence.getObjectAt(2)).getValue();
  256. BigInteger v4 = ((ASN1Integer) sequence.getObjectAt(3)).getValue();
  257. BigInteger v5 = ((ASN1Integer) sequence.getObjectAt(4)).getValue();
  258. BigInteger v6 = ((ASN1Integer) sequence.getObjectAt(5)).getValue();
  259. BigInteger v7 = ((ASN1Integer) sequence.getObjectAt(6)).getValue();
  260. BigInteger v8 = ((ASN1Integer) sequence.getObjectAt(7)).getValue();
  261. BigInteger v9 = ((ASN1Integer) sequence.getObjectAt(8)).getValue();
  262. keySpec = new RSAPrivateCrtKeySpec(v2, v3, v4, v5, v6, v7, v8, v9);
  263. }
  264.  
  265. RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME).generatePrivate(keySpec);
  266. return priKey;
  267. }
  268.  
  269. /**
  270. * RSA公鑰加密
  271. *
  272. * @param value
  273. * 加密字符串
  274. * @param publicKey
  275. * 公鑰
  276. * @return 密文
  277. * @throws Exception
  278. * 加密過(guò)程中的異常信息
  279. */
  280. public static String rsaEncrypt(String value, RSAPublicKey publicKey) throws Exception {
  281. if (value == null || value.length() == 0)
  282. return "";
  283.  
  284. // RSA加密
  285. Cipher cipher = Cipher.getInstance("RSA");
  286. cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  287. byte[] buffer = cipher.doFinal(value.getBytes("utf-8"));
  288.  
  289. // 使用hex格式輸出公鑰
  290. StringBuffer result = new StringBuffer();
  291. for (int i = 0; i < buffer.length; i++) {
  292. result.append(String.format("%02x", buffer[i]));
  293. }
  294. return result.toString();
  295. }
  296.  
  297. /**
  298. * RSA私鑰解密
  299. *
  300. * @param value
  301. * 加密字符串
  302. * @param privateKey
  303. * 私鑰
  304. * @return 明文
  305. * @throws Exception
  306. * 解密過(guò)程中的異常信息
  307. */
  308. public static String rsaDecrypt(String value, RSAPrivateKey privateKey) throws Exception {
  309. if (value == null || value.length() == 0)
  310. return "";
  311.  
  312. byte[] buffer = new byte[value.length() / 2];
  313. for (int i = 0; i < buffer.length; i++) {
  314. buffer[i] = (byte) Integer.parseInt(value.substring(i * 2, i * 2 + 2), 16);
  315. }
  316.  
  317. // RSA解密
  318. Cipher cipher = Cipher.getInstance("RSA");
  319. cipher.init(Cipher.DECRYPT_MODE, privateKey);
  320. buffer = cipher.doFinal(buffer);
  321. return new String(buffer, "utf-8");
  322. }
  323.  
  324. /**
  325. * RSA簽名
  326. *
  327. * @param value
  328. * 加密字符串
  329. * @param privateKey
  330. * 私鑰
  331. * @param halg
  332. * 加密算法,如MD5, SHA1, SHA256, SHA384, SHA512等
  333. * @return 簽名
  334. * @throws Exception
  335. * 簽名過(guò)程中的異常信息
  336. */
  337. public static String sign(String value, RSAPrivateKey privateKey, String halg) throws Exception {
  338.  
  339. Signature s = Signature.getInstance(halg.toUpperCase().endsWith("WithRSA") ? halg : (halg + "WithRSA"));
  340.  
  341. s.initSign(privateKey);
  342. s.update(value.getBytes("utf-8"));
  343.  
  344. byte[] buffer = s.sign();
  345.  
  346. // 使用hex格式輸出公鑰
  347. StringBuffer result = new StringBuffer();
  348. for (int i = 0; i < buffer.length; i++) {
  349. result.append(String.format("%02x", buffer[i]));
  350. }
  351. return result.toString();
  352. }
  353.  
  354. /**
  355. * RSA簽名驗(yàn)證
  356. *
  357. * @param value
  358. * 加密字符串
  359. * @param publicKey
  360. * 公鑰
  361. * @param halg
  362. * 加密算法,如MD5, SHA1, SHA256, SHA384, SHA512等
  363. * @return 簽名合法則返回true,否則返回false
  364. * @throws Exception
  365. * 驗(yàn)證過(guò)程中的異常信息
  366. */
  367. public static boolean verify(String value, RSAPublicKey publicKey, String signature, String halg) throws Exception {
  368. Signature s = Signature.getInstance(halg.toUpperCase().endsWith("WithRSA") ? halg : (halg + "WithRSA"));
  369. s.initVerify(publicKey);
  370. s.update(value.getBytes("utf-8"));
  371.  
  372. byte[] buffer = new byte[signature.length() / 2];
  373. for (int i = 0; i < buffer.length; i++) {
  374. buffer[i] = (byte) Integer.parseInt(signature.substring(i * 2, i * 2 + 2), 16);
  375. }
  376.  
  377. return s.verify(buffer);
  378. }
  379.  
  380. }

生成公鑰和私鑰:  

  1. // 生成公私鑰
  2. Object[] rsaKey = RsaUtil.generateRsaKey(usePKCS8); //usePKCS8=true表示是否成PKCS8格式的公私秘鑰,否則乘車(chē)PKCS1格式的公私秘鑰
  3. byte[] publicKey = (byte[]) rsaKey[0];
  4. byte[] privateKey = (byte[]) rsaKey[1];

生成秘鑰后,需要保存,一般保存到pem文件中: 

  1. // 保存到pem文件,filePath是保存目錄
  2. RsaUtil.writeToPem(publicKey, false, filePath + "rsa.pub");
  3. RsaUtil.writeToPem(privateKey, true, filePath + "rsa.pem");

可以保存到pem文件中,當(dāng)然也可以從pem文件中讀取了:  

  1. // 從Pem文件讀取公私鑰,filePath是文件目錄
  2. byte[] publicKey = RsaUtil.readFromPem(filePath + "rsa.pub");
  3. byte[] privateKey = RsaUtil.readFromPem(filePath + "rsa.pem");

還可以從crt證書(shū)中讀取公鑰,而crt文件不包含私鑰,因此需要單獨(dú)獲取私鑰: 

  1. // 從crt文件讀取公鑰(crt文件中不包含私鑰),filePath是文件目錄
  2. byte[] publicKey = RsaUtil.readPublicKeyFromCrt(filePath + "demo.crt");
  3. byte[] privateKey = RsaUtil.readFromPem(filePath + "demo.key");

pfx文件中包含了公鑰和私鑰,可以很方便就讀取到:  

  1. // 從pfx文件讀取公私鑰,filePath是文件目錄
  2. Object[] rsaKey = RsaUtil.readFromPfx(filePath + "demo.pfx", "123456");
  3. byte[] publicKey = (byte[]) rsaKey[0];
  4. byte[] privateKey = (byte[]) rsaKey[1];

有時(shí)候我們還可能需要進(jìn)行秘鑰的轉(zhuǎn)換:  

  1. // Pkcs8格式公鑰轉(zhuǎn)換為Pkcs1格式公鑰
  2. publicKey = RsaUtil.pkcs8ToPkcs1(false, publicKey);
  3. // Pkcs8格式私鑰轉(zhuǎn)換為Pkcs1格式私鑰
  4. privateKey = RsaUtil.pkcs8ToPkcs1(true, privateKey);
  5. // Pkcs1格式公鑰轉(zhuǎn)換為Pkcs8格式公鑰
  6. publicKey = RsaUtil.pkcs1ToPkcs8(false, publicKey);
  7. // Pkcs1格式私鑰轉(zhuǎn)換為Pkcs8格式私鑰
  8. privateKey = RsaUtil.pkcs1ToPkcs8(true, privateKey);

有了公鑰和私鑰,接下就就能實(shí)現(xiàn)加密、解密、簽名、驗(yàn)證簽名等操作了:  

  1. RSAPublicKey rsaPublicKey = RsaUtil.generatePublicKey(usePKCS8, publicKey);
  2. RSAPrivateKey rsaPrivateKey = RsaUtil.generatePrivateKey(usePKCS8, privateKey);
  3.  
  4. String encryptText = RsaUtil.rsaEncrypt(text, rsaPublicKey);
  5. System.out.printf("【%s】經(jīng)過(guò)【RSA】加密后:%s\n", text, encryptText);
  6.  
  7. String decryptText = RsaUtil.rsaDecrypt(encryptText, rsaPrivateKey);
  8. System.out.printf("【%s】經(jīng)過(guò)【RSA】解密后:%s\n", encryptText, decryptText);
  9.  
  10. String signature = RsaUtil.sign(text, rsaPrivateKey, "MD5");
  11. System.out.printf("【%s】經(jīng)過(guò)【RSA】簽名后:%s\n", text, signature);
  12.  
  13. boolean result = RsaUtil.verify(text, rsaPublicKey, signature, "MD5");
  14. System.out.printf("【%s】的簽名【%s】經(jīng)過(guò)【RSA】驗(yàn)證后結(jié)果是:" + result, text, signature);

這里完整的demo代碼:

  1. import java.security.interfaces.RSAPrivateKey;
  2. import java.security.interfaces.RSAPublicKey;
  3.  
  4. public class RsaMain {
  5.  
  6. public static void main(String[] args) {
  7. try {
  8. String text = "上山打老虎";
  9. boolean usePKCS8 = true; // usePKCS8=true表示是否成PKCS8格式的公私秘鑰,否則乘車(chē)PKCS1格式的公私秘鑰
  10. String filePath = RsaUtil.class.getClassLoader().getResource("").getPath();
  11. System.out.printf("文件路徑:%s\n", filePath);// 存放pem,crt,pfx等文件的目錄
  12. byte[] publicKey, privateKey;// 公鑰和私鑰
  13.  
  14. // 生成公私鑰
  15. Object[] rsaKey = RsaUtil.generateRsaKey(usePKCS8); // usePKCS8=true表示是否成PKCS8格式的公私秘鑰,否則乘車(chē)PKCS1格式的公私秘鑰
  16. publicKey = (byte[]) rsaKey[0];
  17. privateKey = (byte[]) rsaKey[1];
  18. // 從Pem文件讀取公私鑰,filePath是文件目錄
  19. // publicKey = RsaUtil.readFromPem(filePath + "rsa.pub");
  20. // privateKey = RsaUtil.readFromPem(filePath + "rsa.pem");
  21. // 從pfx文件讀取公私鑰,filePath是文件目錄
  22. // Object[] rsaKey = RsaUtil.readFromPfx(filePath + "demo.pfx",
  23. // "123456");
  24. // publicKey = (byte[]) rsaKey[0];
  25. // privateKey = (byte[]) rsaKey[1];
  26. // 從crt文件讀取公鑰(crt文件中不包含私鑰),filePath是文件目錄
  27. // publicKey = RsaUtil.readPublicKeyFromCrt(filePath + "demo.crt");
  28. // privateKey = RsaUtil.readFromPem(filePath + "demo.key");
  29.  
  30. // 保存到pem文件,filePath是保存目錄
  31. RsaUtil.writeToPem(publicKey, false, filePath + "rsa.pub");
  32. RsaUtil.writeToPem(privateKey, true, filePath + "rsa.pem");
  33.  
  34. // Pkcs8格式公鑰轉(zhuǎn)換為Pkcs1格式公鑰
  35. publicKey = RsaUtil.pkcs8ToPkcs1(false, publicKey);
  36. // Pkcs8格式私鑰轉(zhuǎn)換為Pkcs1格式私鑰
  37. privateKey = RsaUtil.pkcs8ToPkcs1(true, privateKey);
  38. // Pkcs1格式公鑰轉(zhuǎn)換為Pkcs8格式公鑰
  39. publicKey = RsaUtil.pkcs1ToPkcs8(false, publicKey);
  40. // Pkcs1格式私鑰轉(zhuǎn)換為Pkcs8格式私鑰
  41. privateKey = RsaUtil.pkcs1ToPkcs8(true, privateKey);
  42.  
  43. RSAPublicKey rsaPublicKey = RsaUtil.generatePublicKey(usePKCS8, publicKey);
  44. RSAPrivateKey rsaPrivateKey = RsaUtil.generatePrivateKey(usePKCS8, privateKey);
  45.  
  46. String encryptText = RsaUtil.rsaEncrypt(text, rsaPublicKey);
  47. System.out.printf("【%s】經(jīng)過(guò)【RSA】加密后:%s\n", text, encryptText);
  48.  
  49. String decryptText = RsaUtil.rsaDecrypt(encryptText, rsaPrivateKey);
  50. System.out.printf("【%s】經(jīng)過(guò)【RSA】解密后:%s\n", encryptText, decryptText);
  51.  
  52. String signature = RsaUtil.sign(text, rsaPrivateKey, "MD5");
  53. System.out.printf("【%s】經(jīng)過(guò)【RSA】簽名后:%s\n", text, signature);
  54.  
  55. boolean result = RsaUtil.verify(text, rsaPublicKey, signature, "MD5");
  56. System.out.printf("【%s】的簽名【%s】經(jīng)過(guò)【RSA】驗(yàn)證后結(jié)果是:" + result, text, signature);
  57.  
  58. } catch (Exception e) {
  59. // TODO Auto-generated catch block
  60. e.printStackTrace();
  61. }
  62. }
  63. }

以上就是Java 實(shí)現(xiàn)RSA非對(duì)稱(chēng)加密算法的詳細(xì)內(nèi)容。

0 人點(diǎn)贊