密钥交换算法之六
2021-12-10 本文已影响0人
喏喏2021
1. 背景
大数据量加密,及加密安全性,在对称加密上已经得到了保证,剩下的问题是我们怎么来安全地传输密钥呢?
这时就衍生出了密钥交换算法DH,它的安全性完全是由数学理论支撑的。
2. 基本交换过程
- 双方各自生成自己的公钥和私钥
- 将自己公钥传递给对方
- 各自将收到的公钥,结合自己的私钥生成相同的密钥
- 双方可以使用相同的密钥进行对称加密交流
3. 代码示例
public class DHTest {
//用户类
public static class User {
private String name; //名称
private PublicKey publicKey; //密钥对之公钥
private PrivateKey privateKey; //密钥对之私钥
private byte[] secretKey; //生成的相同的密钥
public User(String name) {
this.name = name;
}
//生成本地的密钥对
public void generateKeyPair() {
try {
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("DH");//指定算法
kpGen.initialize(512); //键大小
KeyPair kp = kpGen.generateKeyPair();
this.privateKey = kp.getPrivate(); //得到私钥
this.publicKey = kp.getPublic(); //得到公钥
}catch(Exception e) {
throw new RuntimeException(e);
}
}
//根据对方的公钥生成最终的密钥
public void generateSecretKey(byte[] rcvPubKeyByte) {
try {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(rcvPubKeyByte);
KeyFactory keyFactory = KeyFactory.getInstance("DH");
PublicKey rcvPubKey = keyFactory.generatePublic(keySpec);
//生成本地密钥
KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
keyAgreement.init(this.privateKey);
keyAgreement.doPhase(rcvPubKey, true);
//生成最终的密钥
this.secretKey = keyAgreement.generateSecret();
}catch(Exception e) {
throw new RuntimeException(e);
}
}
//输出公钥私钥,密钥
public void printInfo() {
System.out.println("name:" + this.name);
System.out.printf("公钥:%x\n",new BigInteger(1,this.publicKey.getEncoded()));
System.out.printf("私钥:%x\n",new BigInteger(1,this.privateKey.getEncoded()));
System.out.printf("密钥:%x\n",new BigInteger(1,this.secretKey));
}
}
public static void main(String[] args) {
User user1 = new User("user1");
User user2 = new User("User2");
//生成各自的密钥对
user1.generateKeyPair();
user2.generateKeyPair();
//交换公钥,方便各自生成密钥
user1.generateSecretKey(user2.publicKey.getEncoded());
user2.generateSecretKey(user1.publicKey.getEncoded());
user1.printInfo();
user2.printInfo();
}
}
- 最终输出
name:user1
公钥:3081e030819706092a864886f70d010301308189024100fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e170240678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca402020180034400024100b4ed1960706a54d976dc4960c60a2dfdc33166d103a129a74f2d0b44324240ead0917511e2f68288b7c5e668b49a98db3d03bbd91e4ab496fccefad798e9a2e8
私钥:3081d202010030819706092a864886f70d010301308189024100fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e170240678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca40202018004330231008606684ca905aac7d38dc59a11024d0c8ead0b9cb582045c494ed90b3503d3e52daccdd63157b1d1b19a33ba4866d917
密钥:499206a1e50772cd7f9361e5d798942a4fffaca62bd3cc3c5de794528ce26d1fe6f2a27e709d57c3eaf96a10590413d7943d84935d61f16134455586248914f9
name:User2
公钥:3081df30819706092a864886f70d010301308189024100fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e170240678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca40202018003430002405b6986dae1551b61b053323ce6e7eb398df71a30cee556ab81318fc8405e37c31408f2ddfe5af481f565fc60f9991c85dfb4c9faed3981c25048341542cbb54e
私钥:3081d202010030819706092a864886f70d010301308189024100fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e170240678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4020201800433023100fafa6943274c4cdc612ca383b6251dbef545023f1919e2d07dbc1466b906e7b0e58934fe57a02bbf34388df009d5ee97
密钥:499206a1e50772cd7f9361e5d798942a4fffaca62bd3cc3c5de794528ce26d1fe6f2a27e709d57c3eaf96a10590413d7943d84935d61f16134455586248914f9
通过以上输出可以看到,双方的公钥、私钥都是不一样的,但最终得到的密钥却是一样的,成功!
看累了,眼睛休息一下,点击赞一个吧!