一、实习题目 : 基于RSA算法加密
二、实习过程
【注】本次实验源码随附件压缩上传。 (联系我)
1. 实验要求分析
首先对本次实验的实验要求和实验目的进行了详细的分析,获取本次实验的核心任务。本次实验旨在完成RSA算法,从而实现对数字的加解密操作。其中要用到RSA的算法过程作为指导:
(1)生成两个大素数p和q;
(2)计算n = p*q,m = (p-1)*(q-1);
(3)选择随机数e(即加密密钥),使之满足0<e<m,gcd(e,m);
(4)计算解密密钥d = e ^ -1 mod m;
(5)公布整数n 和 加密密钥e;
(6)加密运算:
。
(7)解密运算:
。
(8)这里加解密过程满足:
。
2. 对字符串完成加解密操作
(1) 第一步就是完成对传递参数的判断,判断其是不是素数,这次实验中独立写成一个类PrimeNumber,其中的public static boolean isPrimeNum(int sourceNumber)静态类用来获取其判断结果。
(2) 然后在主要的实现类RSADemo中使用getPrimeNum()获取p和q,并使用这两个素数得到n、m,并在其中调用另一个实现类BiggestCompany中的一个静态类public static int getBiggestCompany(int m,int n)来判断产生的一个随机数publicKey是不是满足0<e<m,gcd(e,m),最终获取公钥publicKey。
(3) 根据上面得1.(4)中给出的要求,从而完成一个方法public void getPrivate_key() 来获取私钥privateKey。
(4) 按照题目中的要求实现加密public int encrypt() 和 解密public int decrypt()两个函数方法,通过这连个方法,完成对输入的数字进行加密和解密,但是只有在公钥和私钥是同时产生的一对的时候才可以进行相互的加解密操作,否则会出现错误。
3. 在main函数中,完成对主要类RSADemo得调用,并在其中实现循环的加解密操作
实现效果如下图所示:

效果图
三、实习总结
完成本次实验实现了两次,第一次做大部分是在实验课上,但是那次的代码在一次不慎操作中丢失了,于是又在今天开始书写这段代码,但是可能是对RSA算法,不是很了解的缘故,几天又一次学习了这个算法的全过程。这样的一次学习和上网查找相关的讲解,逐渐了解了其中的本质有了一定的了解。RSA算法的安全性建立在大整数分解难题之上,该算法所用的公约和私钥是一对足够大的奇素数的函数,但是考虑到算法的复杂度和现在的以学习为主要目的的现状,在产生两个所谓的大素数时做了简化,只是产生1~1000之间的素数,其中的加密安全性并不理想,但是已经是可以反映问题的本质了。
【源码】PrimeNumber 类
//package Practice3;
import java.security.SecureRandom;
public class PrimeNumber {
public PrimeNumber(){}
public static boolean isPrimeNum(int sourceNumber){
boolean flag = true;
if (sourceNumber <= 0)
throw new IllegalArgumentException("sourceNumber是不合法的参数!");
for (int i = 2; i <= Math.sqrt(sourceNumber); i++) {
if (sourceNumber % i == 0)
flag = false;
if (flag == false)
break;
}
return flag;
}
}
BiggestCompany 类
//package Practice3;
public class BiggestCompany {
public BiggestCompany(){}
public static int getBiggestCompany(int m,int n){
int gcd;
if (n==0)
gcd = m;
else
gcd = getBiggestCompany(n, m%n);
return gcd;
}
}
RSADemo 类
//package Practice3;
import java.util.Scanner;
public class RSADemo {
protected int p;
protected int q;
protected int n;
protected int m;
protected int publicKey;
protected int privateKey;
protected int gcd;
protected final int CRYPT_OK = 1;
protected final int CRYPT_ERROR = 0;
private void getPrimeNum() {//两个素数、获取公钥
p = (int) (Math.random() * 100 + 1);
while (!PrimeNumber.isPrimeNum(p)) {
p = (int) (Math.random() * 100 + 1);
}
q = (int) (Math.random() * 100 + 1);
while (!PrimeNumber.isPrimeNum(q)) {
q = (int) (Math.random() * 100 + 1);
}
System.out.println("第一个素数p:" + p);
System.out.println("第二个素数q:" + q);
n = p * q;
m = (p - 1) * (q - 1);
System.out.println("n=p*q=:" + n);
System.out.println("m=(p-1)*(q-1)=:" + m);
publicKey = (int) (Math.random() * m);
gcd = BiggestCompany.getBiggestCompany(publicKey, m);
while (gcd != 1) {
publicKey = (int) (Math.random() * m);
gcd = BiggestCompany.getBiggestCompany(publicKey, m);
}
System.out.println("公钥publicKey为:" + publicKey);
}
public void getPrivate_key() {//获取私钥
getPrimeNum();
long value = 1;
for (long i = 1;; i++) {
value = i * m + 1;
// System.out.println("value: "+value);
if ((value % publicKey == 0)
&& (value / publicKey < m)) {
this.privateKey = (int) (value / publicKey);
break;
}
}
System.out.println("私钥privateKey为:" + privateKey);
}
public int colum(int y, int n, int key) {//计算其中的E(k) = (x ^ e) mod n x∈ Z(n),D(k) = (y ^ d) mod n y∈ Z(n)
int mul;
if (key == 1)
mul = y % n;
else
mul = y * colum(y, n, key - 1) % n;
return mul;
}
public int encrypt() {//加密操作
Scanner scan = new Scanner(System.in);
System.out.println("请输入明文:");
int text = Integer.parseInt(scan.nextLine());
System.out.println("输入明文为: " + text);
// 加密
int secretword = colum(text, n, publicKey);
System.out.println("所得的密文为:" + secretword);
if (secretword!=text)
return CRYPT_OK;
else
return CRYPT_ERROR;
}
public int decrypt() {//解密操作
Scanner scan = new Scanner(System.in);
System.out.println("请输入密文:");
int secretword = Integer.parseInt(scan.nextLine());
System.out.println("输入密文为: " + secretword);
// 解密
int text = colum(secretword, n, privateKey);
System.out.println("所得的明文为:" + text);
if (secretword!=text)
return CRYPT_OK;
else
return CRYPT_ERROR;
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
RSADemo rsa = new RSADemo();
// rsa.getPrimeNum();
// rsa.getPrivate_key();
rsa.getPrivate_key();
int flag = 0;
Scanner scan = new Scanner(System.in);
System.out.println("请输入要进行的操作(1表示加密,-1表示解密,0表示退出):\t");
flag = Integer.parseInt(scan.nextLine());
while(flag==1 || flag==-1){
if (flag==1)
rsa.encrypt();
else
rsa.decrypt();
System.out.println("请输入要进行的操作(1表示加密,-1表示解密,0表示退出):\t");
flag = Integer.parseInt(scan.nextLine());
}
System.out.println("您已退出本程序");
}
}