本帖最后由 吴明霞 于 2022-5-13 15:21 编辑
RSA算法
一、RSA算法的简介 1977年,三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。从那时直到现在,RSA算法一直是最广为使用的"非对称加密算法"。非对称加密需要两个密钥来进行加密和解密,这两个秘钥是公开密钥(简称公钥)和私有密钥(简称私钥)。利用公钥对信息进新加密,私钥进行解密。RSA公开密钥密码体制的原理是:根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。 二、RSA算法的原理 RSA密钥生成算法具体如下: (1)随机选取两个素数,作为p和q; (2)计算n=q*p,m=(q-1)*(p-1); (3)随机选取e,使e与m互质; (4)利用扩展欧几里得算法,计算d使d*e mod m=1; (5)得到公钥(e,n)和私钥(d,n). RSA加密算法具体如下: (1)输入明文x(数字); (2)利用模运算的性质,计算密文y=x^e mod n. RSA解密算法具体如下: (1)输入密文y(数字); (2)利用模运算的性质,计算密文x=y^ mod n. 三、代码实现 Utils.java - package rsa;
- import java.io.UnsupportedEncodingException;
- import java.math.BigInteger;
- import java.util.*;
- public class Utils {
- public static List<Integer> setInformation(java.lang.String str) {
- List<Integer> list = new ArrayList<Integer>();
- try {
- byte[] bytes = str.getBytes("utf-8");
- //System.out.println(Arrays.toString(bytes));
- for (byte byt : bytes) {
- list.add((int)(byt));
- }
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- return list;
- }
- /**
- * 判断是否为素数
- *
- */
- public static boolean isPrime(int n) {
- boolean flag = true;
- for (int i = 2; i < n; i++) {
- if (n % i == 0) {
- flag = false;
- break;
- }
- }
- return flag;
- }
- /**
- * 随机选取两个素数
- */
- public static int[] getTwoPrime() {
- int prime[] = new int[2];
- int anInt;
- int i = 0;
- while (i < 2) {
- anInt = new Random().nextInt(200);
- if (isPrime(anInt) && anInt > 10) {
- prime[i] = anInt;
- i++;
- }
- }
- return prime;
- }
- /**
- * 获得N和M
- */
- public static HashMap<Character, Integer> get_N_And_M(int[] twoPrime) {
- HashMap<Character, Integer> map = new HashMap<Character, Integer>();
- int N = twoPrime[0] * twoPrime[1];
- int M = (twoPrime[0] - 1) * (twoPrime[1] - 1);
- System.out.println("素数1:" + twoPrime[0] + "\t\t素数2:" + twoPrime[1]);
- System.out.println("M:" + M + "\t\tN:" + N);
- map.put('N', N);
- map.put('M', M);
- return map;
- }
- /**
- * 随机选取e使得和m互质
- *
- */
- public static int mCoprime(int M) {
- //生成一个介于1和M之间的质数,此质数一定和M互质
- int E;
- while (true) {
- E = new Random().nextInt(200);
- if (isPrime(E) && E > 0 && E < M){
- System.out.println("生成的E是\t:"+E);
- break;
- }
- }
- return E;
- }
- /**
- * 获得D
- * @param M
- * @param E
- * @return
- */
- public static int getD(int M,int E){
- int D=1;
- while(true){
- if((D*E)%M==1){
- break;
- }
- D++;
- }
- return D;
- }
- /**
- * 加密
- */
- public static BigInteger encryption(int msg,int E,int N){
- BigInteger bigInteger = new BigInteger(msg+"");
- BigInteger encryptedText = bigInteger.modPow(new BigInteger(E+""), new BigInteger(N+""));
- // System.out.println("密文:"+encryptedText);
- return encryptedText;
- }
- /**
- * 解密
- */
- public static BigInteger decrypt(BigInteger encryptedText,int D,int N){
- BigInteger plainText = encryptedText.modPow(new BigInteger(D+""), new BigInteger(N+""));
- return plainText;
- }
-
- public static String getInformation(List<BigInteger> list){
- String sd = "";
- Iterator<BigInteger> iterator = list.iterator();
- while(iterator.hasNext()){
- BigInteger next = iterator.next();
- Integer integer = new Integer(next + "");
- char b = (char)integer.byteValue();
- sd+=b;
- }
- return sd;
- }
- }
复制代码
test.java
- package rsa;
- import java.math.BigInteger;
- import java.util.*;
- import static rsa.Utils.*;
- public class RSA {
- public static void main(String[] args) {
- System.out.println("----------获取密钥和公钥RSA算法核心----------");
- int[] twoPrime = getTwoPrime();
- HashMap<Character, Integer> n_and_m = get_N_And_M(twoPrime);
- int N = n_and_m.get('N');
- int M = n_and_m.get('M');
- int E = mCoprime(M);
- int D = getD(M,E);
- System.out.println("生成的D是\t:"+D);
- System.out.println("******************公钥**************");
- System.out.println("公钥\t:("+E+","+N+")");
- System.out.println("私钥\t:("+D+","+N+")");
- System.out.println("-----------------输入明文-----------------");
- System.out.print("请输入要加密的信息:");
- String str = new Scanner(System.in).nextLine();
- List<Integer> information = setInformation(str);
- System.out.println("转码后的信息(char转byte):"+ information.toString());
- System.out.println("-------------------加密-------------------");
- List<BigInteger> encryptionList = new ArrayList<BigInteger>();
- Iterator<Integer> iterator = information.iterator();
- while(iterator.hasNext()){
- encryptionList.add(encryption(iterator.next(), E, N));//加密装入集合
- }
- System.out.println("公钥加密后的信息(char字符数组对应的byte数组):"+encryptionList.toString());
- System.out.println("-------------------解密-------------------");
- List<BigInteger> decryptList = new ArrayList<BigInteger>();
- for (int i = 0; i < encryptionList.size(); i++) {
- decryptList.add(decrypt(encryptionList.get(i),D,N));//解密装入集合
- }
- System.out.println("私钥解密后的信息(char字符数组对应的byte数组):"+decryptList.toString());
- BigInteger encryption = encryption(1234, E, N);
- decrypt(encryption,D,N);
- System.out.println("-------------------解密后的信息-------------------");
- String s = getInformation(decryptList);
- System.out.println("解密后的明文:"+s);
- }
- }
复制代码 四、运行结果
运行截图1:
运行截图2:
|