目录
1. 概述
非对称加密需要两把密钥:公钥和私钥,他们是一对,如果用公钥对数据加密,那么只能用对应的私钥解密。如果用私钥对数据加密,只能用对应的公钥进行解密。因为加密和解密用的是不同的密钥,所以称为非对称加密。
非对称加密的缺点:运算速度非常慢,比对称加密要慢很多。
从DH算法我们可以看到,公钥-私钥组成的密钥对是非常有用的加密方式,因为公钥是可以公开的,而私钥是完全保密的,由此奠定了非对称加密的基础。
非对称加密的典型算法就是RSA算法,它是由Ron Rivest,Adi Shamir,Leonard Adleman这三个人一起发明的,所以用他们三个人的姓氏首字母缩写表示。
2. 非对称加密算法案例
小明要加密一个消息发送给小红,他应该首先向小红索取她的公钥,然后,他用小红的公钥加密,把加密结果发送给小红,此文件只能由小红的私钥解开,因为小红的私钥在她自己手里,所以,除了小红,没有任何人能解开此加密结果。
// RSA
public class Work04 {
public static void main(String[] args) throws Exception {
// 明文:
byte[] plain = "Hello, encrypt use RSA".getBytes("UTF-8");
// 创建公钥/私钥对
Human hong = new Human("小红");
Human ming = new Human("小明");
// 小明使用小红的公钥进行加密
// 1.获取小红的公钥
PublicKey hongPublicKey = hong.publickey;
System.out.println(String.format("小红的public key(公钥): %x", new BigInteger(1, hongPublicKey.getEncoded())));
// 2.使用公钥加密
byte[] encrypted = hong.encrypt(plain, hongPublicKey);
System.out.println(String.format("encrypted(加密): %x", new BigInteger(1, encrypted)));
// 小红使用自己的私钥解密:
// 1.获取小红的私钥,并输出
PrivateKey hongPrivateKey = hong.privatekey;
System.out.println(String.format("小红的private key(私钥): %x", new BigInteger(1, hongPrivateKey.getEncoded())));
// 2.使用私钥解密
byte[] decrypted = hong.decrypt(encrypted);;
System.out.println("decrypted(解密): " + new String(decrypted, "UTF-8"));
}
}
// 用户类
class Human {
// 姓名
String name;
// 私钥:
PrivateKey privatekey;
// 公钥:
PublicKey publickey;
// 构造方法
public Human(String name) throws GeneralSecurityException {
// 初始化姓名
this.name = name;
// 生成公钥/私钥对:
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");
kpGen.initialize(1024);
KeyPair kp = kpGen.generateKeyPair();
this.privatekey = kp.getPrivate();
this.publickey = kp.getPublic();
}
// 把私钥导出为字节
public PrivateKey getPrivateKey() {
return this.privatekey;
}
// 把公钥导出为字节
public PublicKey getPublicKey() {
return this.publickey;
}
// 用公钥加密
public byte[] encrypt(byte[] message,PublicKey publickey) throws GeneralSecurityException {
// 使用公钥进行初始化
Cipher cp = Cipher.getInstance("RSA");
cp.init(Cipher.ENCRYPT_MODE,publickey);
return cp.doFinal(message);
}
// 用私钥解密:
public byte[] decrypt(byte[] input) throws GeneralSecurityException {
// 使用私钥进行初始化
Cipher cp = Cipher.getInstance("RSA");
cp.init(Cipher.DECRYPT_MODE,this.privatekey);
return cp.doFinal(input);
}
}
RSA的公钥和私钥都可以通过getEncoded()方法获得以byte[]表示的二进制数据,并根据需要保存到文件中。
以RSA算法为例,它的密钥有256/512/1024/2048/4096等不同的长度。长度越长,密码强度越大,当然计算速度也越慢。
小结:
非对称加密就是加密和解密使用的不是相同的密钥,只有同一个公钥-私钥对才能正常加解密;