JAVA实现RSA加密解密

好久好久才搞出的RSA

花了一天的时间才搞出来
在这里插入图片描述
RSA没有任何理解上的难度,只不过换成大数来实现BigInteger

BigInteger
关于java BigInteger用法:

1import java.util.Scanner; 2import java.util.Arrays; 3import java.util.Base64; 4import java.math.*; 5import java.security.SecureRandom; 6import java.io.*; 7import java.util.Random; 8public class RSA{ 9 final static Base64.Decoder decoder = Base64.getDecoder(); 10 final static Base64.Encoder encoder = Base64.getEncoder(); 11 public static BigInteger x,y; 12public static void main(String []args) throws Exception 13{ 14 System.out.println("*******************************RSA**********************************"); 15 System.out.println("text输入可以是任何字符,最大为多大我也没试过"); 16 System.out.println("*******************************RSA**********************************"); 17 int stop=0; 18 while(stop==0) 19 { 20 System.out.println("Please select 0加密 or 1解密:"); 21 int select; 22 Scanner input0=new Scanner(System.in); 23 select=input0.nextInt(); 24 if(select==0) 25 {System.out.println("Please input your text:"); 26 Scanner input=new Scanner(System.in); 27 String text=input.nextLine(); 28 encrypt(text); 29 } 30 else 31 { 32 System.out.println("Please input your text:"); 33 Scanner input1=new Scanner(System.in); 34 String text1=input1.nextLine(); 35 /* System.out.println("Please input your Privatekey:"); 36 Scanner input2=new Scanner(System.in); 37 String key=input2.nextLine(); 38 System.out.println("Please input your n:"); 39 Scanner input3=new Scanner(System.in); 40 String n=input3.nextLine(); 41 BigInteger N=new BigInteger(n);*/ 42 decode(text1); 43 } 44 System.out.println("***********press 0 to continue,press 1 to stop************"); 45 Scanner input4=new Scanner(System.in); 46 stop=input4.nextInt(); 47 } 48} 49static void encrypt(String text) throws IOException//加密 50{ 51byte []binary=text.getBytes("UTF-8"); 52 String text1=encoder.encodeToString(binary); 53 byte []binarys=text1.getBytes(); 54BigInteger text2=new BigInteger(binarys); 55Random rnd = new Random(); 56BigInteger p=BigInteger.probablePrime(512,rnd); 57BigInteger q=BigInteger.probablePrime(1024,rnd); 58BigInteger e=new BigInteger("65535"); 59BigInteger n=p.multiply(q); 60System.out.println("n:"+n.toString()); 61BigInteger fn=p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE)); 62for(int h=0;;h++) 63{ 64if(!fn.gcd(e).equals(BigInteger.ONE)) 65e=new BigInteger(512,rnd); 66exgcd(e,fn); 67BigInteger temp=x; 68exgcd(temp,fn); 69if(!e.equals(x)) 70 continue; 71x=temp; 72if(!x.equals(BigInteger.ONE)) 73 break; 74} 75BigInteger d; 76if(x.add(BigInteger.ONE).abs().subtract(x.abs()).equals(BigInteger.ONE)) 77d=x; 78else d=fn.add(x); 79File i=new File("CA.txt"); 80FileWriter in=new FileWriter(i); 81PrintWriter input=new PrintWriter(in); 82System.out.println("e:"+e); 83System.out.println("fn:"+fn); 84System.out.println("d:"+d); 85System.out.println("明文:"+text2); 86BigInteger C=fastmodmi(text2,e,n); 87String str1=d.toString(); 88String str2=n.toString(); 89input.println(str1); 90input.println(str2); 91System.out.println("密文:"+C); 92in.close();input.close(); 93} 94static void decode(String text) throws IOException 95{ 96BigInteger text1=new BigInteger(text); 97FileReader in=new FileReader("CA.txt"); 98BufferedReader input=new BufferedReader(in); 99String d=input.readLine(); 100String n=input.readLine(); 101in.close(); 102BigInteger N=new BigInteger(n); 103BigInteger privatekey=new BigInteger(d); 104BigInteger m=fastmodmi(text1,privatekey,N); 105String text2=""; 106byte []binarys=m.toByteArray(); 107for(int i=0;i<binarys.length;i++) 108 text2=text2+(char)binarys[i]; 109System.out.println("明文:"+new String(decoder.decode(text2), "UTF-8")); 110} 111static BigInteger fastmodmi(BigInteger m,BigInteger e,BigInteger n)//快速幂 112{ 113BigInteger temp=m; 114BigInteger mod1=new BigInteger("1"); 115for(int i=0;;i++) 116{ 117if(e.and(BigInteger.ONE).equals(BigInteger.ONE)) 118 mod1=mod1.multiply(temp).mod(n); 119e=e.shiftRight(1); 120if(e.equals(BigInteger.ZERO)) 121 break; 122temp=temp.multiply(temp).mod(n); 123} 124return mod1; 125} 126public static void exgcd(BigInteger a,BigInteger p){//求模的逆元 127 if(p.equals(BigInteger.ZERO)){ 128 x=BigInteger.ONE; 129 y=BigInteger.ZERO; 130 return; 131 } 132 exgcd(p,a.mod(p)); 133 BigInteger k=x; 134 x=y; 135 y=k.subtract(a.divide(p).multiply(y)); 136} 137} 138 139

**本来很简单的一个算法,但是期间出现了各种错误。
1、一开始是没将base64的编码给改成整数,导致BigInteger一直报错。
2、快速幂一开始也没搞清楚谁是谁,哎
3、最惨的是我一直没弄懂私钥怎么求,还以为是一个一个的试,发现要花好多的时间。后来又怀疑大数的分解因子是个难题这句话,才反应过来n的欧拉函数通过两个素数求,但是这两个素数只有我知道,其他人什么都有不知道,也不能分解出,原来如此!辗转相除法出现在我的眼前。
4、最后一个问题是n太小,而加密的明文有太大,那就不可能解密的了,哎。
**

代码交流 2021