RSA算法原理及其实现

时间:2019-09-18
本文章向大家介绍RSA算法原理及其实现,主要包括RSA算法原理及其实现使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1、准备步骤:

1)取8-bit的两个素数(质数)p、q

2)n = p * q,计算 n 的欧拉函数m(表示在小于等于n的正整数之中,与 n 构成互质关系的数的个数),当 p 和 q 均为质数时,m = (p - 1) * (q - 1)

3)随机选取一个整数e,满足条件 1 < e < m 且 e 与 m 互质(但不能选择 m - 1,否则公钥和私钥将相同)

4)找出一个整数 d,使得 e * d mod m = 1,即找出 e 模 m 的逆元(扩展欧几里得算法求逆元,之前的一篇随笔有说明)

5)公钥为(n, e),私钥为(n, d)

2、加密过程

对明文的e次方后除以n求余数,即求:(mingwen)^e mod n

3、解密过程

对密文进行d次方后除以n求余数,即求:(miwen)^d mod n

4、加密及解密实现(对学号+姓名加密):

  1 import java.util.ArrayList;
  2 
  3 public class Main {
  4     static ArrayList<Integer> suArr = new ArrayList<>();
  5     static int[] xy = new int[2];
  6 
  7     public static void main(String[] args) {
  8         // 由于题目要求取8-bit的两个素数 p,q 因此素数集合的最大值不超过255
  9         int max = 255, p = 0, q = 0, n, m, e = -1, index = 0;
 10         char[] myInfo = "1700802067GJQ".toCharArray();
 11         int[] miwen = new int[myInfo.length];
 12         char[] mingwen = new char[myInfo.length];
 13         suArr.add(2);
 14 
 15         for (int i = 3; i <= max; i++) {
 16             if (isSuShu(i))
 17                 suArr.add(i);
 18         }
 19 
 20         // 保证取到的两个素数不相等
 21         while (p == q) {
 22             p = getRanNum(suArr.size());
 23             q = getRanNum(suArr.size());
 24         }
 25 
 26         n = p * q;
 27         m = (p - 1) * (q - 1);
 28 
 29         // 求得公钥为(n, e)
 30         for (int i = 2; i < m; i++) {
 31             if (isHuZhi(m, i) == 1) {
 32                 e = i;
 33                 break;
 34             }
 35         }
 36 
 37         if (e != -1) {
 38             exGcd(e, m);
 39             /*
 40             根据要求(e*d)%m=1求得的d(即xy[0])可能为负数,因此当其为负数时要将其转化为正数,转换的原理为:
 41             a%b=(a%b+b)%b
 42             当a为负数且b为正数时可使用上述公式将a转换为正数
 43             */
 44             if (xy[0] < 0) xy[0] = (xy[0] % m + m) % m;
 45             System.out.println("p为" + String.valueOf(p) + ",q为" + String.valueOf(q));
 46             System.out.println("公钥为(" + String.valueOf(n) + ", " + String.valueOf(e) + "),私钥为(" + String.valueOf(n) + ", " + String.valueOf(xy[0]) + ")");
 47 
 48             // 公钥进行加密(mingwen)^e mod n
 49             for (char c : myInfo) {
 50                 miwen[index++] = myPow((int) c, e, n);
 51             }
 52             System.out.print("加密后的密文:");
 53             for (int c : miwen) {
 54                 System.out.print(c + " ");
 55             }
 56             System.out.println();
 57 
 58             index = 0;
 59             // 私钥进行解密(miwen)^d mod n
 60             for (int i : miwen) {
 61                 mingwen[index] = (char) myPow(miwen[index], xy[0], n);
 62                 index++;
 63             }
 64 
 65             System.out.print("解密后的明文:");
 66             for (char c : mingwen) {
 67                 System.out.print(c);
 68             }
 69 
 70         }
 71 
 72     }
 73 
 74     // 判断一个数是否为素数
 75     public static boolean isSuShu(int num) {
 76         int max = (int) Math.sqrt(num);
 77         for (int i = 2; i <= max; i++) {
 78             if (num % i == 0)
 79                 return false;
 80         }
 81         return true;
 82     }
 83 
 84     // 在素数数组中随机取一个数
 85     public static int getRanNum(int size) {
 86         return suArr.get((int) (Math.random() * (size)));
 87     }
 88 
 89     // 判断两个数是否互质
 90     public static int isHuZhi(int a, int b) {
 91         return b == 0 ? a : isHuZhi(b, a % b);
 92     }
 93 
 94     // 扩展欧几里得算法求得e模m的逆元,从而得到私钥(n, xy[0]),即(n, d)
 95     public static void exGcd(int a, int b) {
 96         if (b == 0) {
 97             xy[0] = 1;
 98             xy[1] = 0;
 99         } else {
100             exGcd(b, a % b);
101             int x = xy[0];
102             xy[0] = xy[1];
103             xy[1] = x - (a / b) * xy[1];
104         }
105     }
106 
107     public static int myPow(int a, int b, int m) {
108         int res = 1;
109         a %= m;
110         while (b != 0) {
111             if ((b & 1) == 1)
112                 res = (res * a) % m;
113             a = (a * a) % m;
114             b >>= 1;
115         }
116         return res;
117     }
118 }
119 
120 /*
121  * 参考: https://www.jianshu.com/p/fbb8bf7baa97
122  * https://www.cnblogs.com/shuaihui520/p/8954788.html
123  * https://www.cnblogs.com/linkzijun/p/6151486.html
124  */

原文地址:https://www.cnblogs.com/GjqDream/p/11543073.html