美文网首页
RSA加密算法Java应用

RSA加密算法Java应用

作者: 指尖上的榴莲 | 来源:发表于2017-12-15 23:26 被阅读11次

一.什么是RSA算法

1977年,三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。从那时直到现在,RSA算法一直是最广为使用的"非对称加密算法"。

这种算法非常可靠,密钥越长,它就越难破解。根据已经披露的文献,目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。

RSA算法包括RSA加密方案和RSA签名方案。下文主要讨论RSA加密算法。

二.RSA加密算法的执行步骤

1.生成密钥

第一步,随机选择两个不相等的质数p和q。
第二步,计算p和q的乘积n,即n=pq,这里将n表示成二进制的长度就是密钥长度。实际应用中,RSA密钥一般是1024位,重要场合则为2048位。
第三步,计算n的欧拉函数φ(n),φ(n) = (p-1)(q-1)。
第四步,随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质。
第五步,计算e对于φ(n)的模反元素d。所谓"模反元素"就是指有一个整数d,可以使得ed被φ(n)除的余数为1,即ed ≡ 1 (mod φ(n))
第六步,将n和e封装成公钥,n和d封装成私钥,即pk=(n,e),sk=(n,d)。

2.加密

假设A要向B发送待加密的信息m,A就要用B的公钥 (n,e) 对m进行加密生成密文c,然后将密文c发送给B。这里需要注意,m必须是整数(字符串可以取ascii值或unicode值),且m必须小于n。
所谓"加密",就是算出下式的c :
me ≡ c (mod n)

3.解密

B收到A发送过来的密文c以后,使用自己的私钥(n,d)对c进行解密,就可以得到明文m。
所谓“解密”,就是算出下式的m:
cd ≡ m (mod n)

三.RSA加密算法的原理

RSA算法原理(一)
RSA算法原理(二)

四.RSA加密算法Java应用

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.*;
import java.security.*;

public class RSAEncrypt {
    //指定加密算法为RSA
    private static final String ALGORITHM = "RSA";
    //指定密钥长度
    private static final int KEY_SIZE = 1024;
    //指定私钥存放文件
    private static final String PRIVATE_KEY_FILE = "PrivateKey";
    //指定公钥存放文件
    private static final String PUBLIC_KEY_FILE = "PublicKey";

    /**
     * 生成密钥
     */
    private void generateKey() {
        try {
            //指定随机数源
            SecureRandom secureRandom = new SecureRandom();
            //为RSA算法创建一个KeyPairGenerator对象
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
            //初始化KeyPairGenerator对象
            keyPairGenerator.initialize(KEY_SIZE, secureRandom);
            //生成密钥对
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            //获取私钥
            Key privateKey = keyPair.getPrivate();
            //获取公钥
            Key publicKey = keyPair.getPublic();
            //将私钥和公钥写入文件
            ObjectOutputStream privateKeyStream = new ObjectOutputStream(
                    new FileOutputStream(PRIVATE_KEY_FILE));
            ObjectOutputStream publicKeyStream = new ObjectOutputStream(
                    new FileOutputStream(PUBLIC_KEY_FILE));
            privateKeyStream.writeObject(privateKey);
            publicKeyStream.writeObject(publicKey);
            privateKeyStream.close();
            publicKeyStream.close();
        } catch (NoSuchAlgorithmException | IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 加密算法
     * @param plaintext  明文
     * @return  密文
     */
    public String encrypt(String plaintext){
        try {
            //读取文件获取公钥
            ObjectInputStream inputStream = new ObjectInputStream(
                    new FileInputStream(PUBLIC_KEY_FILE));
            Key publicKey = (Key) inputStream.readObject();
            inputStream.close();
            //得到Cipher对象来实现RSA加密算法
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] bytes = cipher.doFinal(plaintext.getBytes());
            BASE64Encoder base64Encoder = new BASE64Encoder();
            return base64Encoder.encode(bytes);
        } catch (IOException | ClassNotFoundException | NoSuchPaddingException
                | NoSuchAlgorithmException | InvalidKeyException | BadPaddingException
                | IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解密算法
     * @param ciphertext  密文
     * @return  明文
     */
    public String decrypt(String ciphertext){
        try {
            //读取文件获取私钥
            ObjectInputStream inputStream = new ObjectInputStream(
                    new FileInputStream(PRIVATE_KEY_FILE));
            Key privateKey = (Key) inputStream.readObject();
            inputStream.close();
            //得到Cipher对象来实现RSA解密算法
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            BASE64Decoder base64Decoder = new BASE64Decoder();
            byte[] bytes = base64Decoder.decodeBuffer(ciphertext);
            return new String(cipher.doFinal(bytes));
        } catch (IOException | ClassNotFoundException | NoSuchPaddingException
                | NoSuchAlgorithmException | InvalidKeyException | BadPaddingException
                | IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        RSAEncrypt rsaEncrypt = new RSAEncrypt();
        rsaEncrypt.generateKey();
        String message = "Hello World";
        String ciphertext = rsaEncrypt.encrypt(message);
        System.out.println("ciphertext: " + ciphertext);

        String plaintext = rsaEncrypt.decrypt(ciphertext);
        System.out.println("plaintext: " + plaintext);
    }
}

打印结果为:

ciphertext: R6rW79OHQQvEBtchRETqQuNVKZ5ePV3K3XSknqYX1b1MqEGPTE3aZaHFAc98jsvLf3wLOAXKvGxT
VFUcTNom5W01mz9U8BhU6g3I07ZJWwYJDKrMuoaE26RlkWILa2f2lGDVUJ+2xB75EqZzq8bAxlEn
oqv8d+vaaoWGJ8PIpAQ=
plaintext: Hello World

参考:
RSA加密算法Java应用实例

相关文章

网友评论

      本文标题:RSA加密算法Java应用

      本文链接:https://www.haomeiwen.com/subject/fdrjwxtx.html