一.什么是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加密算法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应用实例