密钥交换算法——DH算法


密钥交换算法概述

在之前的对称加密算法中,基于"密钥"解决了数据加密和解密的问题,但在实际案例开发中,密钥该如何传递呢?
在不安全的信道上传递加密文件是没有问题的,因为黑客拿到加密文件没有用。但是,如何在不安全的信道上安全地传输密钥?
要解决这个问题,就需要使用密钥交换算法:DH算法(Diffie-Hellman算法)。DH算法解决了密钥在双方不直接传递密钥的情况下完成密钥交换,这个神奇的交换原理完全由数学理论的支持。


密钥交换算法的底层逻辑

在了解了密钥交换算法DH算法之后,那么它是怎么交换?怎么实现的呢?
大致可以这样理解;
在这里插入图片描述
在DH算法的交换中,双方的私钥和协商后的共享密钥并没有在网络上进行传输,双方传输的只是自己的公钥,而且传输过程中的p,g,A和B是无法推算出K的。所以,DH算法的本质就是双方各自生成自己的私钥和公钥,私钥仅对自己可见,然后交换公钥,并根据自己的私钥和对方的公钥,生成最终的密钥secretKey,DH算法通过数学定律保证了双方各自计算出的secretKey是相同的

案例实现

代码如下(示例):

//DH算法
public class Work03 {
	public static void main(String[] args) {
		// Bob和Alice:
        Person bob = new Person("Bob");
        Person alice = new Person("Alice");
        
        // 各自生成KeyPair: 公钥+私钥
        bob.generateKeyPair();
        alice.generateKeyPair();

        // 双方交换各自的PublicKey(公钥):
        // Bob根据Alice的PublicKey生成自己的本地密钥(共享公钥):
        bob.generateSecretKey(alice.publicKey.getEncoded()); 
        // Alice根据Bob的PublicKey生成自己的本地密钥(共享公钥):
        alice.generateSecretKey(bob.publicKey.getEncoded());
        // 检查双方的本地密钥是否相同:
        bob.printKeys();
        alice.printKeys();
	}
}
//用户类
class Person {
	public final String name; // 姓名
	// 密钥
	public PublicKey publicKey; // 公钥
	private PrivateKey privateKey; // 私钥
	private byte[] secretKey; // 本地秘钥(共享密钥)
	// 构造方法
	public Person(String name) {
		this.name = name;
	}
	// 生成本地KeyPair:(公钥+私钥)
	public void generateKeyPair() {
		try {
			// 创建DH算法的“秘钥对”生成器
			KeyPairGenerator kpGen = KeyPairGenerator.getInstance("DH");
			kpGen.initialize(512);		
			//生成一个密钥对
			KeyPair kp = kpGen.generateKeyPair();
			this.publicKey=kp.getPublic();
			this.privateKey=kp.getPrivate();		
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}
	// 按照 "对方的公钥" => 生成"共享密钥"
	public void generateSecretKey(byte[] receivedPubKeyBytes) {
		try {
			//从byte[]数组中恢复PublicKey
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(receivedPubKeyBytes);			
			//根据DH算法获取KeyFactory
			KeyFactory kf = KeyFactory.getInstance("DH");	
			//通过KeyFactory创建公钥
			PublicKey receivedPublicKey=kf.generatePublic(keySpec);		
			//创建密钥协议对象(用于密钥协商)
			KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
			keyAgreement.init(this.privateKey);//初始自己的私钥
			keyAgreement.doPhase(receivedPublicKey, true);//根据对方的公钥
			
			//生成SecretKey本地密钥(共享公钥)
			this.secretKey=keyAgreement.generateSecret();			
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		}		
	}
	public void printKeys() {
		System.out.printf("Name: %s\n", this.name);
		System.out.printf("Private key: %x\n", new BigInteger(1, this.privateKey.getEncoded()));
		System.out.printf("Public key: %x\n", new BigInteger(1, this.publicKey.getEncoded()));
		System.out.printf("Secret key: %x\n", new BigInteger(1, this.secretKey));
	}
}

总结

  • DH算法是一种密钥交换协议,通信双方通过不安全的信道协商密钥,然后进行对称加密传输。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值