当前位置:   article > 正文

RSA算法

RSA算法

RSA非对称加密技术实现过程,代码如下:

  1. package com.zhongji.utils;
  2. import java.math.BigInteger;
  3. import java.util.Random;
  4. public class RSA {
  5. private final static int numLength = 1024;//素数长度
  6. private final static int accuracy = 100;//素数的准确率为1-(2^(-accuracy))
  7. //获取最大公约数
  8. private BigInteger getGCD(BigInteger a, BigInteger b) {
  9. if (b.byteValue() == 0) return a;
  10. return getGCD(b, a.mod(b));
  11. }
  12. //扩展欧几里得方法,计算 ax + by = 1中的x与y的整数解(a与b互质)
  13. private static BigInteger[] extGCD(BigInteger a, BigInteger b) {
  14. if (b.signum() == 0) {
  15. return new BigInteger[]{a, new BigInteger("1"), new BigInteger("0")};
  16. } else {
  17. BigInteger[] bigIntegers = extGCD(b, a.mod(b));
  18. BigInteger y = bigIntegers[1].subtract(a.divide(b).multiply(bigIntegers[2]));
  19. return new BigInteger[]{bigIntegers[0], bigIntegers[2], y};
  20. }
  21. }
  22. //超大整数超大次幂然后对超大的整数取模,利用蒙哥马利乘模算法,
  23. //(base ^ exp) mod n
  24. //依据(a * b) mod n=(a % n)*(b % n) mod n
  25. private static BigInteger expMode(BigInteger base, BigInteger exp, BigInteger mod) {
  26. BigInteger res = BigInteger.ONE;
  27. //拷贝一份防止修改原引用
  28. BigInteger tempBase = new BigInteger(base.toString());
  29. //从左到右实现简答
  30. for (int i = 0; i < exp.bitLength(); i++) {
  31. if (exp.testBit(i)) {//判断对应二进制位是否为1
  32. res = (res.multiply(tempBase)).mod(mod);
  33. }
  34. tempBase = tempBase.multiply(tempBase).mod(mod);
  35. }
  36. return res;
  37. }
  38. //产生公钥与私钥
  39. public static SecretKey generateKey(BigInteger p, BigInteger q) {
  40. //令n = p * q。取 φ(n) = (p-1) * (q-1)。
  41. BigInteger n = p.multiply(q);
  42. //计算与n互质的整数个数 欧拉函数
  43. BigInteger fy = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
  44. //取 e ∈ [1 < e < φ(n) ] ,( n , e )作为公钥对,这里取65537
  45. BigInteger e = new BigInteger("65537");
  46. //计算ed与fy的模反元素d。令 ed mod φ(n) = 1,计算d,然后将( n , d ) 作为私钥对
  47. BigInteger[] bigIntegers = extGCD(e, fy);
  48. //计算出的x不能是负数,如果是负数,则进行x=x+fy。使x为正数,但是x<fy。
  49. BigInteger x = bigIntegers[1];
  50. if (x.signum() == -1) {
  51. x = x.add(fy);
  52. }
  53. //返回计算出的密钥
  54. return new SecretKey(n, e, x);
  55. }
  56. public static SecretKey generateKey() {
  57. BigInteger[] pq = getRandomPQ();
  58. return generateKey(pq[0], pq[1]);
  59. }
  60. //加密
  61. public static BigInteger encrypt(BigInteger text, SecretKey.PublicKey publicKey) {
  62. return expMode(text, publicKey.e, publicKey.n);
  63. }
  64. //解密
  65. public static BigInteger decrypt(BigInteger cipher, SecretKey.PrivateKey privateKey) {
  66. return expMode(cipher, privateKey.d, privateKey.n);
  67. }
  68. //加密
  69. public static String encrypt(String text, SecretKey.PublicKey publicKey) {
  70. return encrypt(new BigInteger(text.getBytes()), publicKey).toString();
  71. }
  72. //解密
  73. public static String decrypt(String chipper, SecretKey.PrivateKey privateKey) {
  74. BigInteger bigInteger = expMode(new BigInteger(chipper), privateKey.d, privateKey.n);
  75. byte[] bytes = new byte[bigInteger.bitLength() / 8 + 1];
  76. for (int i = 0; i < bytes.length; i++) {
  77. for (int j = 0; j < 8; j++) {
  78. if (bigInteger.testBit(j + i * 8)) {
  79. bytes[bytes.length - 1 - i] |= 1 << j;
  80. }
  81. }
  82. }
  83. return new String(bytes);
  84. }
  85. //产生两个随机1024位大质数
  86. public static BigInteger[] getRandomPQ() {
  87. BigInteger p = BigInteger.probablePrime(numLength, new Random());
  88. while (!p.isProbablePrime(accuracy)) {
  89. p = BigInteger.probablePrime(numLength, new Random());
  90. }
  91. BigInteger q = BigInteger.probablePrime(numLength, new Random());
  92. while (!q.isProbablePrime(accuracy)) {
  93. q = BigInteger.probablePrime(numLength, new Random());
  94. }
  95. return new BigInteger[]{p, q};
  96. }
  97. //密匙对
  98. static class SecretKey {
  99. BigInteger n, e, d;
  100. public SecretKey(BigInteger n, BigInteger e, BigInteger d) {
  101. this.n = n;
  102. this.e = e;
  103. this.d = d;
  104. }
  105. public PublicKey getPublicKey() {
  106. return new PublicKey(n, e);
  107. }
  108. public PrivateKey getPrivateKey() {
  109. return new PrivateKey(n, d);
  110. }
  111. //密钥
  112. static class PrivateKey {
  113. public BigInteger n, d;
  114. public PrivateKey(BigInteger n, BigInteger d) {
  115. this.n = n;
  116. this.d = d;
  117. }
  118. }
  119. //公钥
  120. static class PublicKey {
  121. public BigInteger n, e;
  122. public PublicKey(BigInteger n, BigInteger e) {
  123. this.n = n;
  124. this.e = e;
  125. }
  126. }
  127. }
  128. public static void main(String[] args) {
  129. SecretKey secretKey = RSA.generateKey();
  130. //明文内容不要超过1024位,超过后需要分段加密
  131. String text = "Hello world";
  132. String chipper = RSA.encrypt(text, secretKey.getPublicKey());
  133. System.out.println("加密后:\n" +
  134. //密文长度可能会随着随机密钥的改变而改变,最长不超过2048
  135. "密文二进制长度:" + new BigInteger(chipper).bitLength()
  136. + "\n"
  137. + chipper);
  138. String origin = RSA.decrypt(chipper, secretKey.getPrivateKey());
  139. System.out.println("解密后:\n" + origin);
  140. }
  141. }

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

闽ICP备14008679号