【密码学】一文读懂Diffie-Hellman密钥交换协议

简介: 注意这个算法是基于离散对数的,如果对于离散对数不了解的读者可以查看我之前的对于离散对数讲解的文章。

一文读懂Diffie-Hellman密钥交换算法


[W%0A6F~T@E)A@W0HN%_RQV.jpg

Diffie-Hellman密钥交换算法

注意这个算法是基于离散对数的,如果对于离散对数不了解的读者可以查看我之前的对于离散对数讲解的文章。


算法描述

首先选定一个素数q和这个素数的一个原根, 这两个数字作为公开的信息,然后对于想要交换数据的Alice和Bob, 他们分别选择两个随机的整数和这两个随机整数都小于q, 然后分别计算, , 然后对于A来说,把发送给B, 同理,对于B来说把发送给A, 然后A和B分别计算, , 这两种方式计算的K是一样的,下面简单来证明一下:

image.png

这样看起来,可能觉得我上面啰嗦了这么一大段,说的是个啥,下面来看一个图,简单的理解一下这个过程。

XXT0{)25YF`N{O{4NO7%_I5.png

image.gifDiffie-Hellman密钥交换算法过程

这里,Alice和Bob通过这个算法获得了一个Key, 到这里有读者可能会发问了,难道这就结束了?下面来具体分析一下这个过程,假设攻击者的手段特别强大,能够截获所有的消息,那么对于攻击者来说,所能获取的信息有:

  • q = 353
  • = 3
  • = 40
  • = 248

那么,如果说攻击者要获取到密钥(K = 160), 那么实际上攻击者需要计算或者说, 对于这个例子来说,穷举是能出来的,但是密码学当中,显然是不会采用这么小的素数的,如果对于一个大的素数比如2048bit的大素数来说,穷举显然是不可能的。


中间人攻击

  1. 攻击者首先生成两个随机的私钥和, 然后分别计算他们的对应的公钥,
  2. Alice把自己生成的公钥发送给Bob
  3. 攻击者截获Alice发送给Bob的, 然后发送给Bob, 同时计算得到
  4. Bob收到攻击者发来的此时,Bob并不知道这实际上不是Alice发来的消息,然后Bob按照发送来的公钥来计算
  5. Bob计算自己的公钥并发送给Alice
  6. 攻击者再次截获, 然后将发送给Alice,同时攻击者计算
  7. Alice收到攻击者发送来的, 同时计算, 此时同样Alice也不知道这个密钥实际上不是来自Bob的

到这里,虽然Alice和Bob已经完成了密钥交换,但是实际上这个密钥已经被攻击者替换了,攻击者可以拿到他们通信的所有的信息。

下面来看一个具体的例子,还是以上面说过的Alice和Bob为例,和上图一样,依然采用q = 356,  = 3为例。

72740[XOOOF`L%551D)UQ[X.png

中间人攻击

从图中可以看出,尽管Alice和Bob交换了密钥,但是攻击者却可以拿到他们通信的信息,因此, 对于密钥交换协议来说,并没有办法去抵御这种攻击,因为密钥交换协议并没有去验证密钥发送者的身份,也就是Alice无法判断密钥确实是来自Bob的,同理Bob也没法判断密钥确实是来自Alice的,如上面的第四条和第七条所示。这个后续可以通过签名+证书来解决。


代码示例

对于这个算法来说,代码相对来说比较简单,对于如何去找到一个素数以及如何找到这个素数的一个原根,相关代码可以查看之前的文章,在这里就不啰嗦了,我直接选择了一个素数进行运算的。

use num_bigint::{BigUint};
fn calc_y(p: &BigUint, alpha: &BigUint, x: &BigUint) -> BigUint {
    alpha.modpow(&x, &p)
}
fn calc_k(p: &BigUint, x: &BigUint, y: &BigUint) -> BigUint {
    y.modpow(&x, &p)
}
#[cfg(test)]
mod test {
    use num_bigint::{BigUint, RandBigInt};
    use crate::diffie_hellman::{calc_y, calc_k};
    #[test]
    fn test() {
        let p = BigUint::from(104729u64);
        let alpha = BigUint::from(17596u64);
        let mut rng = rand::thread_rng();
        let xa = rng.gen_biguint(16);
        println!("[private] Alice selected X is {}", xa);
        let ya = calc_y(&p, &alpha, &xa);
        println!("[public] Alice calculate Y is {}", ya);
        let xb = rng.gen_biguint(16);
        println!("[private] Bob selected X is {}", xb);
        let yb = calc_y(&p, &alpha, &xb);
        println!("[public] Bob calculate Y is {}", yb);
        let ka = calc_k(&p, &xa, &yb);
        println!("[private] Alice calculate Key is {}", ka);
        let kb = calc_k(&p, &xb, &ya);
        println!("[private] Bob calculate Key is {}", kb);
    }
}


总结

有了这个密钥交换的算法,实际上就可以在不安全的信道当中进行密钥交换了,这也就弥补了对称加密体系当中密钥下发的问题,但是这样做产生了一个新的问题,也就是存在中间人攻击的可能,密钥交换协议不能够对抗中间人攻击,因为他并没有验证通信双方的身份,也就是Alice没法确认这个消息是来自Bob的,这个问题实际上是可以通过数字签名+证书来解决的,在这一篇文章当中就不过多描述解决方案了。

相关文章
|
7月前
|
机器学习/深度学习 算法 安全
【加密算法】RSA非对称加密算法简介
【加密算法】RSA非对称加密算法简介
|
存储 算法 安全
【密码学】非对称加密算法 - ECDH
由于 ECC 密钥具有很短的长度,所以运算速度比较快。到目前为止,对于 ECC 进行逆操作还是很难的,数学上证明不可破解,ECC 算法的优势就是性能和安全性高。实际应用可以结合其他的公开密钥算法形成更快、更安全的公开密钥算法,比如结合 DH 密钥形成 ECDH 密钥协商算法,结合数字签名 DSA 算法组成 ECDSA 数字签名算法。ECDH算法常常用来进行密钥的协商,协商好密钥后,用来解决上面的密钥分配问题,将对称加密的密钥安全的传到对端设备。算法加密/解密数字签名密钥交换RSA✅✅✅❌。
3496 0
|
Web App开发 安全 算法
一起学习密码学:对称加密与非对称加密
本文是 一起学习密码学 系列第 1 篇。
一起学习密码学:对称加密与非对称加密
|
4月前
|
算法 安全 网络安全
Diffie-Hellman (DH) 算法的工作原理
【8月更文挑战第23天】
538 0
|
7月前
|
算法 安全 关系型数据库
Diffie-Hellman密钥交换协议
Diffie-Hellman密钥交换协议
143 6
|
7月前
|
算法 安全 数据安全/隐私保护
公钥密码学:解密加密的魔法世界
【4月更文挑战第20天】
77 2
公钥密码学:解密加密的魔法世界
|
7月前
|
算法 安全 关系型数据库
非对称加密算法Diffie-Hellman算法
Diffie-Hellman算法是一种非对称加密方法,用于在不安全的通道上建立共享密钥。它基于两个用户交换公开的p和g(大素数和其原根)以及各自的随机数计算得出相同的秘密密钥s/s'。算法的安全性依赖于离散对数问题的困难性,防止未授权者计算出密钥。该算法与对称加密(如AES)结合,先生成共享密钥,再用于加密实际通信,确保消息安全。
186 2
|
7月前
|
安全 算法 网络安全
|
存储 算法 安全
【算法】快速了解各种不同的加密算法-总结
快速加密和解密:对称加密算法的加密和解密过程使用相同的密钥,因此加密和解密速度较快,适合处理大量数据。
290 0
|
并行计算 算法 搜索推荐
【密码学】 对称加密算法
在密码学中,加密算法按照实现方式可分为对称加密算法和非对称加密算法。对称加密算法指的是加密方和解密方使用相同的密钥进行加密和解密,即双方使用共同的密钥。在对称加密算法使用的过程中,数据发送方将明文数据通过密钥进行加密生成密文数据,将密文数据发送给接收方,接收方收到密文数据后,通过密钥进行解密,将其恢复成明文数据。这就要求接收方要首先知道密钥,这需要发送方先将密钥通过安全方式发给接收方,通常会使用非对称加密例如ECDH算法来传输密钥(非对称密钥会在下章讲解)。
342 0
【密码学】 对称加密算法