Java安全学习笔记(十一)-RSA算法加密和解密

xiaoxiao2021-02-28  94

RSA算法是使用整数进行加密和解密运算的, 加密:在RSA公钥中包含了两个信息:公钥对应的整数e和用于取模的整数n。对于明文数字m,计算密文的公式是: m^e mod n. 解密:跟加密类似,私钥对应的指数e和用于取模的整数m.其中模m和加密时的加密的模n完全相同。对于密文数字d,计算公式d^e mod n。加密和解密最大的不同在于幂e不同。 本实例以加密和解密一个字符串”I am a student” 为例,演示了如何使用生成的RSA公钥文件进行加密。 使用RSA算法加密的技术要点如下: 1.用FileInputStream获取公钥 2.用RSAPublicKey类中的方法获取公钥的参数(e,n) 3.用BigInteger m=new BigInteger(ptext);来获取明文整数(m) 4.执行计算 使用RSA算法解密的技术要点如下: 1.利用FileInputStream读取密文Enc_RSA.dat 2.利用RSAPrivateKey类的readObject()方法获取私钥 3.利用RSAPrivateKey类获取私钥的BigInteger类型的参数(e,m) 4.利用BigInteger的modPow()方法执行解密的计算 5.解析出明文整型数对应的字符串

package core; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStreamWriter; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; /** * RSA算法加密和解密 * */ public class Password_Test { public static void main(String[] args) { try { new Password_Test(); Encryption_RSA(); Decryption_RSA(); } catch (Exception e) { e.printStackTrace(); } } public Password_Test() throws Exception { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");// 生成实现RSA算法的KeyPairGenerator对象 kpg.initialize(1024);// 初始化确定密钥的大小 KeyPair kp = kpg.generateKeyPair();// 生成密钥对 PublicKey pbkey = kp.getPublic();// 创建公钥 PrivateKey prkey = kp.getPrivate();// 创建私钥 /* 保存公钥和私钥 */ // 保存公钥 FileOutputStream file1 = new FileOutputStream("Skey_RSA_pub.dat"); ObjectOutputStream ob1 = new ObjectOutputStream(file1);// 创建ObjectOutputStream ob1.writeObject(pbkey); // 保存私钥 FileOutputStream file2 = new FileOutputStream("Skey_RSA_priv.dat"); ObjectOutputStream ob2 = new ObjectOutputStream(file2);// 创建ObjectOutputStream ob2.writeObject(prkey); //关闭流 ob1.close(); ob2.close(); } public static void Encryption_RSA() throws Exception{ System.out.println("根据公钥生成密文:"); String string="I am a student"; //获取公钥 FileInputStream f_in=new FileInputStream("Skey_RSA_pub.dat"); ObjectInputStream o_in=new ObjectInputStream(f_in); RSAPublicKey pbk=(RSAPublicKey) o_in.readObject(); //获取参数e,n BigInteger e=pbk.getPublicExponent();//返回此公钥的指数 BigInteger n=pbk.getModulus();//返回此公钥的模 System.out.println("公钥的指数 e="+e); System.out.println("公钥的模 n="+n); //明文 bit byte bt[]=string.getBytes("UTF8"); BigInteger bit=new BigInteger(bt); //计算密文c,打印 BigInteger c=bit.modPow(e, n); System.out.println("生成密文为: "+ c+"\n"); //保存密文 String save=c.toString(); BufferedWriter out=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("Enc_RSA.dat")));//保存密文 out.write(save, 0, save.length()); o_in.close(); out.close(); } public static void Decryption_RSA() throws Exception{ System.out.println("根据私钥破解密文"); //读取密文 BufferedReader in=new BufferedReader(new InputStreamReader(new FileInputStream("Enc_RSA.dat"))); String ctext=in.readLine(); BigInteger d=new BigInteger(ctext); //读取私钥 FileInputStream f=new FileInputStream("Skey_RSA_priv.dat"); ObjectInputStream b=new ObjectInputStream(f); RSAPrivateKey prk=(RSAPrivateKey) b.readObject(); //获取私钥指数和模 BigInteger e=prk.getPrivateExponent();//返回私钥的指数 BigInteger m=prk.getModulus();//返回私钥的模 BigInteger jie=d.modPow(e, m); System.out.println("私钥的指数 e= "+e); System.out.println("私钥的模 m="+m); System.out.println("解密结果 : "+jie); byte mt[]=jie.toByteArray(); System.out.print("解密后的文本内容为: "); for (int i = 0; i < mt.length; i++) { System.out.print((char)mt[i]); } in.close(); b.close(); } }

源程序解读 (1)Password_Test()构造方法中主要介绍了RSA公钥和私钥文件的生成。创建密钥对生成器KeyPairGenerator,指定非对称加密所使用的算法,常用的有RSA、DSA等。 初始化密钥生成器。关于密钥长度,对于RSA算法,这里指定的其实是RSA算法中所用的模的位数,可以在512-2048之间。 通过KeyPair类的getPublic()和getPrivate()方法获得公钥和私钥对象. (2)Encryption_RSA()方法中主要介绍了如何使用生成好的RSA公钥文件对字符串进行加密。 获取公钥。从生成的公钥文件Skey_RSA_pub.dat中读取公钥,由于生成该文件时使用的是RSA算法,因此从文件读取公钥对象后强制转换为RSAPublicKey类型,以便后续读取RSA算法所需要的参数。 获取明文。明文是一个字符串,为了用整数表达这个字符串,先使用字符串的getByte()方法将其转换为byte类型数组,它其实是字符串中各个字符的二进制表达方式,这一串二进制数转换为一个整数将非常大,因此仍旧使用BigInteger类将这个二进制串转换为整型。 执行加密计算。计算公式: m^e mod n。BigInteger类中已经提供了方法modPow()来执行这个计算。方法返回的结果为密文。 (3)Decryption_RSA()法中主要介绍了如何使用生成好的RSA公钥文件对字符串进行加密。 从生成的密文文件Enc_RSA.dat中读取密文,由于加密后只是一行字符串,因此只要一条readLine()语句即可 从生成的私钥文件Skey_RSA_priv.dat中读取私钥,由于生成该私钥使用的算法是RSA算法,因此从文件读取公钥对象后强制转换为RSAPrivateKey类型,以便后续读取RSA所需的参数。在获取私钥的参数(e,m)的时候可以使用RSAPrivateKey类的getPrivateExponent()和getModulus()方法分别获得私钥中e和m的值。RSA算法解密的结果jie是一个很大的整数,为了计算出其对应的字符串的值,先使用BigInteger类的toByteArray()方法得到代表该整型数的字节数组,然后将数组中每个元素转换为字符,组成字符串。 使用BigInteger的modPow()方法计算前面的公式: d^e mod n,方法返回的结果即是明文。

转载请注明原文地址: https://www.6miu.com/read-28510.html

最新回复(0)