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

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,方法返回的结果即是明文。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值