Java RSA算法进行加密

概要:

RSA算法是使用整数进行加密运算的,在RSA公钥中包含了两个信息:公钥对应的整数e和用于取模的整数n。对于明文数字m,计算密文的公式是:me mod n。

本实例以加密一串最简单的字符串"I am a student"为例,演示了如何使用生成的RSA公钥文件进行加密。

| |目录

技术要点

使用RSA算法加密的技术要点如下:

  • 用FileInputStream获取公钥。

  • 用RSAPublicKey类中的方法获取公钥的参数(e,n)。

  • 用"BigInteger m=new BigInteger(ptext);"来获取明文整数(m)。

  • 执行计算。

代码实现

package net.xsoftlab.baike;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
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;

public class Password_Test {
	public static void main(String[] args) {
		try {
			new Password_Test();
			Encryption_RSA();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public Password_Test() throws Exception {// 构造方法 创建公钥和私钥
		KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");// 生成实现RSA算法的KeyPairGenerator对象。
		kpg.initialize(1024);// 初始化确定密钥的大小
		KeyPair kp = kpg.genKeyPair();// 生成密钥对
		PublicKey pbkey = kp.getPublic();// 创建公钥
		PrivateKey prkey = kp.getPrivate();// 创建私钥
		File file1 = new File("Skey_RSA_pub.dat");
		File file2 = new File("Skey_RSA_priv.dat");
		if (!file1.exists())
			file1.createNewFile();
		if (!file2.exists())
			file2.createNewFile();
		// 保存公钥
		FileOutputStream outputStream1 = new FileOutputStream(file1);
		ObjectOutputStream ob1 = new ObjectOutputStream(outputStream1);// 创建ObjectOutputStream对象
		ob1.writeObject(pbkey); // 将指定的对象写入 ObjectOutputStream。
		// 保存私钥
		FileOutputStream outputStream2 = new FileOutputStream(file2);
		ObjectOutputStream ob2 = new ObjectOutputStream(outputStream2);
		ob2.writeObject(prkey);
	}

	public static void Encryption_RSA() throws Exception {
		System.out.println("根据公钥生成密文:\n");
		String string = "I am a student";
		// 获取公钥及参数e,n
		FileInputStream f_in = new FileInputStream("Skey_RSA_pub.dat");
		ObjectInputStream o_in = new ObjectInputStream(f_in);
		RSAPublicKey pbk = (RSAPublicKey) o_in.readObject();
		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 mi = bit.modPow(e, n);// 生成密文
		System.out.println("生成密文为: " + mi + "\n");// 打印密文
		// 保存密文
		String save = mi.toString();
		BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("Enc_RSA.dat")));
		out.write(save, 0, save.length());
		out.close();
		Decrypt_RSA();
	}

	public static void Decrypt_RSA() throws Exception {
		System.out.println("根据私钥破解密文:\n");
		// 读取密文
		BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("Enc_RSA.dat")));
		String ctext = in.readLine();
		BigInteger mi = new BigInteger(ctext);
		// 读取私钥
		FileInputStream f = new FileInputStream("Skey_RSA_priv.dat");
		ObjectInputStream b = new ObjectInputStream(f);
		RSAPrivateKey prk = (RSAPrivateKey) b.readObject();
		BigInteger d = prk.getPrivateExponent();// 返回此私钥的指数
		BigInteger n = prk.getModulus();// 返回此私钥的模
		System.out.println("私钥的指数 d= " + d);
		System.out.println("私钥的模 n= " + n);
		BigInteger jie = mi.modPow(d, n);// 进行解密操作
		System.out.println("m= " + jie); // 显示解密结果
		byte[] mt = jie.toByteArray();
		System.out.println("解密后的文本内容为: ");
		for (int i = 0; i < mt.length; i++) {
			System.out.print((char) mt[i]);
		}
	}
}

程序解读

  1. Password_Test()构造方法中主要介绍了RSA公钥和私钥文件的生成。

    1. 首先创建密钥对生成器即KeyPair-Generator类型的对象。KeyPairGenerator类是一个工厂类,它通过其中预定义的一个静态方法getInstance()获取KeyPairGenerator类型的对象。getInstance()方法的参数是一个字符串,指定非对称加密所使用的算法,常用的有RSA、DSA等。

    2. 初始化密钥生成器。关于密钥长度,对于RSA算法,这里指定的其实是RSA算法中所用的模的位数,可以在512~2048之间。

    3. 最后获取公钥和私钥,可以通过KeyPair类的getPublic()和getPrivate()方法获得公钥和私钥对象。

  2. Encryption_RSA()方法中主要介绍了如何使用生成好的RSA公钥文件对字符串进行加密。

    1. 首先获取公钥。从生成的公钥文件Skey_RSA_pub.dat中读取公钥,由于生成该文件时使用的是RSA算法,因此从文件读取公钥对象后强制转换为RSAPublicKey类型,以便后面读取RSA算法所需要的参数。

    2. 接着获取明文。明文是一个字符串,为了用整数表达这个字符串,先使用字符串的getBytes()方法将其转换为byte类型数组,它其实是字符串中各个字符的二进制表达方式,这一串二进制数转换为一个整数将非常大,因此仍旧使用BigInteger类将这个二进制串转换为整型。

    3. 最后执行加密计算。计算前面的公式:me mod n。BigInteger类中已经提供了方法modPow()来执行这个计算。底数m执行这个方法,方法modPow()的第一个参数即指数e,第二个参数即模n。方法返回的结果即密文。


评论关闭
评论 还能输入200
评论关闭
评论 还能输入200
  • 全部评论(0)
资料加载中...
已关注 , 取消