之前发了一篇”TripleDes的加解密Java、C#、php通用代码”,后面又有项目用到了Rsa加解密,还是在不同系统之间进行交互,Rsa在不同语言的密钥格式不一样,所以过程中主要还是密钥转换问题,为方便密钥转换,写了一个XML和PEM格式的密钥转换工具,文章后面会提供密钥转换工具的下载地址,通过搜索参考和研究终于搞定了在Java、C#和Php都可以通用的加解密代码,整理了Rsa的加解密代码做个记录,以后可以参考,大家应该都知道Rsa算法,这里就不说明了,直接看代码(代码主要是公钥加密私钥解密,密文统一进行base64编码,密钥长度为2048):

Java版本:

  1. package com.jaamy.common.util;
  2. import java.io.BufferedReader;
  3. import java.io.ByteArrayOutputStream;
  4. import java.io.FileInputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.InputStreamReader;
  8. import java.security.Key;
  9. import java.security.KeyFactory;
  10. import java.security.spec.PKCS8EncodedKeySpec;
  11. import java.security.spec.X509EncodedKeySpec;
  12. import javax.crypto.Cipher;
  13. import org.apache.commons.codec.binary.Base64;
  14. public class RSACryptoUtil {
  15. /**
  16. * 加密算法RSA
  17. */
  18. public static final String KEY_ALGORITHM = "RSA";
  19. /**
  20. * 填充方式
  21. */
  22. public static final String CIPHER_TRANSFORMAT = "RSA/ECB/PKCS1Padding";
  23. /**
  24. * RSA最大加密明文大小
  25. */
  26. private static final int MAX_ENCRYPT_BLOCK = 245;
  27. /**
  28. * RSA最大解密密文大小
  29. */
  30. private static final int MAX_DECRYPT_BLOCK = 256;
  31. /**
  32. * 公钥加密
  33. * @param content 原文
  34. * @param publicKey 公钥
  35. * @param inputCharset 字符编码
  36. * @return 加密后的字符串(base64)
  37. * @throws Exception
  38. */
  39. public static String encryptByPublicKey(String content, String publicKey, String inputCharset)
  40. throws Exception {
  41. byte[] data = content.getBytes(inputCharset);
  42. byte[] keyBytes = Base64.decodeBase64(publicKey);
  43. X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
  44. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  45. Key publicK = keyFactory.generatePublic(x509KeySpec);
  46. // 对数据加密
  47. Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMAT);
  48. cipher.init(Cipher.ENCRYPT_MODE, publicK);
  49. int inputLen = data.length;
  50. ByteArrayOutputStream out = new ByteArrayOutputStream();
  51. int offSet = 0;
  52. byte[] cache;
  53. int i = 0;
  54. // 对数据分段加密
  55. while (inputLen - offSet > 0) {
  56. if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
  57. cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
  58. } else {
  59. cache = cipher.doFinal(data, offSet, inputLen - offSet);
  60. }
  61. out.write(cache, 0, cache.length);
  62. i++;
  63. offSet = i * MAX_ENCRYPT_BLOCK;
  64. }
  65. byte[] encryptedData = out.toByteArray();
  66. out.close();
  67. return Base64.encodeBase64String(encryptedData);
  68. }
  69. /**
  70. * 私钥解密
  71. * @param content 密文(base64)
  72. * @param privateKey 私钥
  73. * @param inputCharset 字符编码
  74. * @return
  75. * @throws Exception
  76. */
  77. public static String decryptByPrivateKey(String content,
  78. String privateKey, String inputCharset) throws Exception {
  79. byte[] encryptedData = Base64.decodeBase64(content);
  80. byte[] keyBytes = Base64.decodeBase64(privateKey);
  81. PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
  82. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  83. Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
  84. Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMAT);
  85. cipher.init(Cipher.DECRYPT_MODE, privateK);
  86. int inputLen = encryptedData.length;
  87. ByteArrayOutputStream out = new ByteArrayOutputStream();
  88. int offSet = 0;
  89. byte[] cache;
  90. int i = 0;
  91. // 对数据分段解密
  92. while (inputLen - offSet > 0) {
  93. if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
  94. cache = cipher
  95. .doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
  96. } else {
  97. cache = cipher
  98. .doFinal(encryptedData, offSet, inputLen - offSet);
  99. }
  100. out.write(cache, 0, cache.length);
  101. i++;
  102. offSet = i * MAX_DECRYPT_BLOCK;
  103. }
  104. byte[] decryptedData = out.toByteArray();
  105. out.close();
  106. return new String(decryptedData, inputCharset);
  107. }
  108. /**
  109. * 从文件中加载密钥字符串
  110. * @return 是否成功
  111. * @throws Exception
  112. */
  113. public static String loadKeyString(String keyFile){
  114. String keyString="";
  115. InputStream in=null;
  116. BufferedReader br=null;
  117. try {
  118. in=RSACryptoUtil.class.getResourceAsStream("/"+keyFile);
  119. br= new BufferedReader(new InputStreamReader(in));
  120. String readLine= null;
  121. StringBuilder sb= new StringBuilder();
  122. while((readLine= br.readLine())!=null){
  123. if(readLine.charAt(0)==\'-\'){
  124. continue;
  125. }else{
  126. sb.append(readLine);
  127. sb.append(\'\r\');
  128. }
  129. }
  130. keyString=sb.toString();
  131. } catch (IOException e) {
  132. } catch (Exception e) {
  133. }finally{
  134. if(br!=null){
  135. try {
  136. br.close();
  137. } catch (IOException e) {
  138. }
  139. }
  140. if(in!=null){
  141. try {
  142. in.close();
  143. } catch (IOException e) {
  144. }
  145. }
  146. }
  147. return keyString;
  148. }
  149. /**
  150. * 从文件中加载密钥字符串 根据文件路径加载
  151. * @return 是否成功
  152. * @throws Exception
  153. */
  154. public static String loadKeyStringByPath(String keyFile){
  155. String keyString="";
  156. InputStream in=null;
  157. BufferedReader br=null;
  158. try {
  159. in = new FileInputStream(keyFile);
  160. br= new BufferedReader(new InputStreamReader(in));
  161. String readLine= null;
  162. StringBuilder sb= new StringBuilder();
  163. while((readLine= br.readLine())!=null){
  164. if(readLine.charAt(0)==\'-\'){
  165. continue;
  166. }else{
  167. sb.append(readLine);
  168. sb.append(\'\r\');
  169. }
  170. }
  171. keyString=sb.toString();
  172. } catch (IOException e) {
  173. System.out.println(e.getMessage());
  174. } catch (Exception e) {
  175. System.out.println(e.getMessage());
  176. }finally{
  177. if(br!=null){
  178. try {
  179. br.close();
  180. } catch (IOException e) {
  181. }
  182. }
  183. if(in!=null){
  184. try {
  185. in.close();
  186. } catch (IOException e) {
  187. }
  188. }
  189. }
  190. return keyString;
  191. }
  192. public static void main(String[] args) throws Exception {
  193. String publicKey = RSAUtils.loadKeyStringByPath("D:/sso_public_key_test.pem");
  194. System.out.println(RSACryptoUtil.encryptByPublicKey("123", publicKey, "utf-8"));
  195. }
  196. }

 

C#版本:

  1. /// <summary>
  2. /// RSA加密+base64
  3. /// </summary>
  4. /// <param name="publickey">公钥</param>
  5. /// <param name="content">原文</param>
  6. /// <returns>加密后的密文字符串</returns>
  7. public static string RSAEncrypt(string publickey, string content)
  8. {
  9. //最大文件加密块
  10. int MAX_ENCRYPT_BLOCK = 245;
  11. RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
  12. byte[] cipherbytes;
  13. rsa.FromXmlString(publickey);
  14. byte[] contentByte = Encoding.UTF8.GetBytes(content);
  15. int inputLen = contentByte.Length;
  16. int offSet = 0;
  17. byte[] cache;
  18. int i = 0;
  19. System.IO.MemoryStream aMS = new System.IO.MemoryStream();
  20. // 对数据分段加密
  21. while (inputLen - offSet > 0)
  22. {
  23. byte[] temp = new byte[MAX_ENCRYPT_BLOCK];
  24. if (inputLen - offSet > MAX_ENCRYPT_BLOCK)
  25. {
  26. Array.Copy(contentByte, offSet, temp, 0, MAX_ENCRYPT_BLOCK);
  27. cache = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);
  28. }
  29. else
  30. {
  31. Array.Copy(contentByte, offSet, temp, 0, inputLen - offSet);
  32. cache = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);
  33. }
  34. aMS.Write(cache, 0, cache.Length);
  35. i++;
  36. offSet = i * MAX_ENCRYPT_BLOCK;
  37. }
  38. cipherbytes = aMS.ToArray();
  39. return Convert.ToBase64String(cipherbytes);
  40. }
  41. /// <summary>
  42. /// RSA解密
  43. /// </summary>
  44. /// <param name="privatekey">私钥</param>
  45. /// <param name="content">密文(RSA+base64)</param>
  46. /// <returns>解密后的字符串</returns>
  47. public static string RSADecrypt(string privatekey, string content)
  48. {
  49. //最大文件解密块
  50. int MAX_DECRYPT_BLOCK = 256;
  51. RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
  52. byte[] cipherbytes;
  53. rsa.FromXmlString(privatekey);
  54. byte[] contentByte = Convert.FromBase64String(content);
  55. int inputLen = contentByte.Length;
  56. // 对数据分段解密
  57. int offSet = 0;
  58. int i = 0;
  59. byte[] cache;
  60. System.IO.MemoryStream aMS = new System.IO.MemoryStream();
  61. while (inputLen - offSet > 0)
  62. {
  63. byte[] temp = new byte[MAX_DECRYPT_BLOCK];
  64. if (inputLen - offSet > MAX_DECRYPT_BLOCK)
  65. {
  66. Array.Copy(contentByte, offSet, temp, 0, MAX_DECRYPT_BLOCK);
  67. cache = rsa.Decrypt(temp, false);
  68. }
  69. else
  70. {
  71. Array.Copy(contentByte, offSet, temp, 0, inputLen - offSet);
  72. cache = rsa.Decrypt(temp, false);
  73. }
  74. aMS.Write(cache, 0, cache.Length);
  75. i++;
  76. offSet = i * MAX_DECRYPT_BLOCK;
  77. }
  78. cipherbytes = aMS.ToArray();
  79. return Encoding.UTF8.GetString(cipherbytes);
  80. }

 

Php版本:

  1. <?php
  2. #私钥
  3. $private_key = \'-----BEGIN PRIVATE KEY-----
  4. MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCocmvQIWD2L9TW
  5. N1uKpLONwHcdy2oaKoW1CtI8PB+S+UjdEuLl3usWEuh3ZgLYloPyD9553SJFn7an
  6. fOplHITBqASOIXt9pi0CkahUPgwCPj4Dke5cT3fsp2i243/FX3afzrcf7FfTrEv/
  7. LT22wF3csqrGt/UhqMcmpWIpPaL8edoCwGRBhghzEWaRwPZ2x5RPg+9qTSy0M7QG
  8. u+8EwYDnNkGGuuIwzNxklclic9Unp96eVp33vOP/LNvz90OcuqGQQcABh+e2ttv6
  9. VzqlRcD1GRhxqkT3erXmgbQAVm6JQHArK1Up10No+lth1tri5TGcL0BEF7PetDIj
  10. jYh+aCLpAgMBAAECggEAPjFI1yaLyzmrxo/Xz5+x36NxF2IUQabziP1+09iK+9Po
  11. cB9aAO9GMvc2N2dFo7wm6Uesp6fa0IQAh2RakoxuA6ZKUEPSeXjSY4Ft+fSSsH1U
  12. njLSI+j/aTQCOIxUj4YIoUZMXJABeVjDEmscvw3VWffpj8c5zXyoUv9696kXNUoa
  13. uHOuphe1UNc3ghFIpWK+7ScxkPB6KtmAFwD4LSbT9OwhPozavBqouQvhLt1bXO8C
  14. ycKq4f1Pzhtt3sq3BRsPwqGhWt1NK95upKQuDnk1kJHjNzScH1FZxhsBHLxwOJ6E
  15. M7HP5Ywh78umusaNPVLMM6+YVWbENg+WZZcXd/XspQKBgQDRIhIukY7m7fRBH0CP
  16. mHi20gUmn7HzXgLxlbcU5n2PMDHHOg8D+Nmz1MnYPRQNwqxJdH8HOk8YQDC2uA+h
  17. BpyCpvPbp6y6SnZw8bhqiNfSHBjEftmg7lUU5xzBiBo6SyCyLkWD2xa/O8Vyh6ut
  18. /G1mQpNNJWWt5b+g5c4i0/fIhwKBgQDOMjGcLS8zHnZ30ZsWUS39iZ5TZXPCldTl
  19. Q9JB5PnB4CajYmQEdw3n9C6mOO42b+3M04mmqo1r0HiNyA9lZQQNsM3KqG+ngGvE
  20. 0DM1cAyuz3Fi3XTIhAbRyXXyVbqBp5Yh2/O2lvrsInusJrimDRgwglquu2GsdVrj
  21. +++b2DFFDwKBgQCkfXLlk/FdK44xZn5mM1vHGBubDIJv0+Lm14Yf90aMyDBu7fh/
  22. fEznSBfWb/wE8riGMg3zxmYNwfdO0Cji04torB4kB5cxE35jSYxupuFxzk2gx9Eu
  23. 5iafgUQ56G4QqaS24PQmSL10fnPHqHRdLa1ygCzRwfdettVpnTbsZ+J9owKBgQDF
  24. o2Tb3o9sPxmsdVNiy8L6TstcAlU3wOfELQK+uFwQ0eoXFvrpMLg6iVmhZ9YkhZp4
  25. hpZdEwLkwXib5ZOkS3PcL4jBZDtJYRVrG2jKIrF1aU60RbJnc+0ZbjHIaxWOqvSD
  26. VdE/RW4TomXKN38rYke6T2feLatMY1wQRG6BgXKQTwKBgQDKfK9Xuqzx+WI4AohT
  27. EwKrQEZUMD+6DTESHHG9As4zMJ9zU+6iPpM4Gw4CzfJZHhPP4dD+TC9NcvvR+GC9
  28. UkwxmZrvP1+6KNFp0DZNk6M9wPZuYM/E63Vy0sFEA+/gFp4vQh8k7N8n/n7DhR3v
  29. kLuPdicfsKcz0thxzyDjv6oR2g==
  30. -----END PRIVATE KEY-----\';
  31. #公钥
  32. $public_key = \'-----BEGIN PUBLIC KEY-----
  33. MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqHJr0CFg9i/U1jdbiqSz
  34. jcB3HctqGiqFtQrSPDwfkvlI3RLi5d7rFhLod2YC2JaD8g/eed0iRZ+2p3zqZRyE
  35. wagEjiF7faYtApGoVD4MAj4+A5HuXE937KdotuN/xV92n863H+xX06xL/y09tsBd
  36. 3LKqxrf1IajHJqViKT2i/HnaAsBkQYYIcxFmkcD2dseUT4Pvak0stDO0BrvvBMGA
  37. 5zZBhrriMMzcZJXJYnPVJ6fenlad97zj/yzb8/dDnLqhkEHAAYfntrbb+lc6pUXA
  38. 9RkYcapE93q15oG0AFZuiUBwKytVKddDaPpbYdba4uUxnC9ARBez3rQyI42Ifmgi
  39. 6QIDAQAB
  40. -----END PUBLIC KEY-----\';
  41. $pi_key = openssl_pkey_get_private($private_key);
  42. $pu_key = openssl_pkey_get_public($public_key);
  43. #公钥加密数据 rsa+base64
  44. $data = "hello world!";
  45. openssl_public_encrypt($data,$encrypted,$pu_key);
  46. $base64_encrypted = base64_encode($encrypted);
  47. echo $base64_encrypted."\n";
  48. #私钥解密数据
  49. openssl_private_decrypt(base64_decode($base64_encrypted),$decrypted_data,$pi_key);
  50. echo $decrypted_data;
  51. ?>

 

Rsa加解密C#和Java、php使用的密钥格式不一样,这里提供一个密钥转换工具:Rsa密钥转换工具v2.0.zip

 

版权声明:本文为jaamy原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/jaamy/archive/2016/12/02/6118814.html