当前位置:   article > 正文

android -------- RSA加密解密算法_android rsapublickeyspec

android rsapublickeyspec

RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用

RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制


网上写法也有很多种,分享一种参考

  1. import java.math.BigInteger;
  2. import java.security.KeyFactory;
  3. import java.security.KeyPair;
  4. import java.security.KeyPairGenerator;
  5. import java.security.NoSuchAlgorithmException;
  6. import java.security.interfaces.RSAPrivateKey;
  7. import java.security.interfaces.RSAPublicKey;
  8. import java.security.spec.RSAPrivateKeySpec;
  9. import java.security.spec.RSAPublicKeySpec;
  10. import java.util.HashMap;
  11. import javax.crypto.Cipher;
  12. public class RSAUtils {
  13. /**
  14. * 生成公钥和私钥
  15. * @throws NoSuchAlgorithmException
  16. *
  17. */
  18. public static HashMap<String, Object> getKeys() throws NoSuchAlgorithmException{
  19. HashMap<String, Object> map = new HashMap<String, Object>();
  20. KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
  21. keyPairGen.initialize(1024);
  22. KeyPair keyPair = keyPairGen.generateKeyPair();
  23. RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  24. RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
  25. map.put("public", publicKey);
  26. map.put("private", privateKey);
  27. return map;
  28. }
  29. /**
  30. * 使用模和指数生成RSA公钥
  31. * 注意:【此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同,如Android默认是RSA
  32. * /None/NoPadding】
  33. *
  34. * @param modulus
  35. * 模
  36. * @param exponent
  37. * 指数
  38. * @return
  39. */
  40. public static RSAPublicKey getPublicKey(String modulus, String exponent) {
  41. try {
  42. BigInteger b1 = new BigInteger(modulus);
  43. BigInteger b2 = new BigInteger(exponent);
  44. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  45. RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);
  46. return (RSAPublicKey) keyFactory.generatePublic(keySpec);
  47. } catch (Exception e) {
  48. e.printStackTrace();
  49. return null;
  50. }
  51. }
  52. /**
  53. * 使用模和指数生成RSA私钥
  54. * 注意:【此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同,如Android默认是RSA
  55. * /None/NoPadding】
  56. *
  57. * @param modulus
  58. * 模
  59. * @param exponent
  60. * 指数
  61. * @return
  62. */
  63. public static RSAPrivateKey getPrivateKey(String modulus, String exponent) {
  64. try {
  65. BigInteger b1 = new BigInteger(modulus);
  66. BigInteger b2 = new BigInteger(exponent);
  67. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  68. RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(b1, b2);
  69. return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
  70. } catch (Exception e) {
  71. e.printStackTrace();
  72. return null;
  73. }
  74. }
  75. /**
  76. * 公钥加密
  77. *
  78. * @param data
  79. * @param publicKey
  80. * @return
  81. * @throws Exception
  82. */
  83. public static String encryptByPublicKey(String data, RSAPublicKey publicKey)
  84. throws Exception {
  85. Cipher cipher = Cipher.getInstance("RSA");
  86. cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  87. // 模长
  88. int key_len = publicKey.getModulus().bitLength() / 8;
  89. // 加密数据长度 <= 模长-11
  90. String[] datas = splitString(data, key_len - 11);
  91. String mi = "";
  92. //如果明文长度大于模长-11则要分组加密
  93. for (String s : datas) {
  94. mi += bcd2Str(cipher.doFinal(s.getBytes()));
  95. }
  96. return mi;
  97. }
  98. /**
  99. * 私钥解密
  100. *
  101. * @param data
  102. * @param privateKey
  103. * @return
  104. * @throws Exception
  105. */
  106. public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey)
  107. throws Exception {
  108. Cipher cipher = Cipher.getInstance("RSA");
  109. cipher.init(Cipher.DECRYPT_MODE, privateKey);
  110. //模长
  111. int key_len = privateKey.getModulus().bitLength() / 8;
  112. byte[] bytes = data.getBytes();
  113. byte[] bcd = ASCII_To_BCD(bytes, bytes.length);
  114. System.err.println(bcd.length);
  115. //如果密文长度大于模长则要分组解密
  116. String ming = "";
  117. byte[][] arrays = splitArray(bcd, key_len);
  118. for(byte[] arr : arrays){
  119. ming += new String(cipher.doFinal(arr));
  120. }
  121. return ming;
  122. }
  123. /**
  124. * ASCII码转BCD码
  125. *
  126. */
  127. public static byte[] ASCII_To_BCD(byte[] ascii, int asc_len) {
  128. byte[] bcd = new byte[asc_len / 2];
  129. int j = 0;
  130. for (int i = 0; i < (asc_len + 1) / 2; i++) {
  131. bcd[i] = asc_to_bcd(ascii[j++]);
  132. bcd[i] = (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++])) + (bcd[i] << 4));
  133. }
  134. return bcd;
  135. }
  136. public static byte asc_to_bcd(byte asc) {
  137. byte bcd;
  138. if ((asc >= '0') && (asc <= '9'))
  139. bcd = (byte) (asc - '0');
  140. else if ((asc >= 'A') && (asc <= 'F'))
  141. bcd = (byte) (asc - 'A' + 10);
  142. else if ((asc >= 'a') && (asc <= 'f'))
  143. bcd = (byte) (asc - 'a' + 10);
  144. else
  145. bcd = (byte) (asc - 48);
  146. return bcd;
  147. }
  148. /**
  149. * BCD转字符串
  150. */
  151. public static String bcd2Str(byte[] bytes) {
  152. char temp[] = new char[bytes.length * 2], val;
  153. for (int i = 0; i < bytes.length; i++) {
  154. val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);
  155. temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
  156. val = (char) (bytes[i] & 0x0f);
  157. temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
  158. }
  159. return new String(temp);
  160. }
  161. /**
  162. * 拆分字符串
  163. */
  164. public static String[] splitString(String string, int len) {
  165. int x = string.length() / len;
  166. int y = string.length() % len;
  167. int z = 0;
  168. if (y != 0) {
  169. z = 1;
  170. }
  171. String[] strings = new String[x + z];
  172. String str = "";
  173. for (int i=0; i<x+z; i++) {
  174. if (i==x+z-1 && y!=0) {
  175. str = string.substring(i*len, i*len+y);
  176. }else{
  177. str = string.substring(i*len, i*len+len);
  178. }
  179. strings[i] = str;
  180. }
  181. return strings;
  182. }
  183. /**
  184. *拆分数组
  185. */
  186. public static byte[][] splitArray(byte[] data,int len){
  187. int x = data.length / len;
  188. int y = data.length % len;
  189. int z = 0;
  190. if(y!=0){
  191. z = 1;
  192. }
  193. byte[][] arrays = new byte[x+z][];
  194. byte[] arr;
  195. for(int i=0; i<x+z; i++){
  196. arr = new byte[len];
  197. if(i==x+z-1 && y!=0){
  198. System.arraycopy(data, i*len, arr, 0, y);
  199. }else{
  200. System.arraycopy(data, i*len, arr, 0, len);
  201. }
  202. arrays[i] = arr;
  203. }
  204. return arrays;
  205. }
  206. }

main方法

  1. public static void main(String[] args) throws Exception {
  2. // TODO Auto-generated method stub
  3. HashMap<String, Object> map = RSAUtils.getKeys();
  4. //生成公钥和私钥
  5. RSAPublicKey publicKey = (RSAPublicKey) map.get("public");
  6. RSAPrivateKey privateKey = (RSAPrivateKey) map.get("private");
  7. //模
  8. String modulus = publicKey.getModulus().toString();
  9. System.out.println(modulus);
  10. //公钥指数
  11. String public_exponent = publicKey.getPublicExponent().toString();
  12. //私钥指数
  13. String private_exponent = privateKey.getPrivateExponent().toString();
  14. System.out.println("公钥指数:"+public_exponent);
  15. System.out.println("私钥指数:"+private_exponent);
  16. //明文
  17. String ming = "123456789 Hello 小笨蛋";
  18. //使用模和指数生成公钥和私钥
  19. RSAPublicKey pubKey = RSAUtils.getPublicKey(modulus, public_exponent);
  20. RSAPrivateKey priKey = RSAUtils.getPrivateKey(modulus, private_exponent);
  21. //加密后的密文
  22. String mi = RSAUtils.encryptByPublicKey(ming, pubKey);
  23. System.out.println("加密后的密文"+mi);
  24. //解密后的明文
  25. String mingn = RSAUtils.decryptByPrivateKey(mi, priKey);
  26. System.out.println("解密后的明文"+mingn);
  27. }

日志(编码太长没截取完)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/478130
推荐阅读
相关标签
  

闽ICP备14008679号