Total Pageviews

Sunday 6 September 2015

为什么Wireshark无法解开使用Diffie-Hellman加密的SSL数据

前段时间升级了服务器的OpenSSL库,今天突然发现使用Wireshark已经无法解密https内容。查了一下资料才知道这是因为新版OpenSSL支持了Diffie-Hellman系列加密算法导致的。我的抓到的数据显示,密钥交换的过程使用的是一种叫ECDH的密钥交换算法。
以前的SSL通信,都是在客户端验证完服务器的证书值得信赖之后,产生随机密钥并直接用服务器的公钥加密发送出去,所以在向Wireshark提供了服务器的私钥之后,Wireshark能用私钥解开网络上传输的客户端生成的密钥,并用它解后续的所有SSL数据。然而用DH算法交换的密钥根本就不会在网络上传输,所以Wireshark自然无法解密了。
下面是从维基百科查到的一个简单版本的DH密钥交换过程:
  1. 一方选择质数p=23和基数g=5发送给另一方,这两个数可以公开明文传输;
  2. 甲方生成私钥a=6,并计算公钥A = ga mod p = 56 mod 23 = 8;
  3. 乙方生成私钥b=15,并计算公钥B = gb mod p = 515 mod 23 = 19;
  4. 甲乙双方互换公钥;
  5. 甲方计算s = Ba mod p = 196 mod 23 = 2;
  6. 乙方计算s = Ab mod p = 815 mod 23 = 2;
  7. 最后双方的共同计算结果2就是接下来进行对称加密传输的密钥。
Wireshark作为中间人,即使以服务器的SSL私钥解密,取得了p、g、A、B,在不知道a、b任一数值的情况下,也难以计算出s是多少。现实情况中,双方选用的p、g、a、b都会非常大,以确保难以被攻破。
要想在Wireshark上进行debug,只能要么在服务器禁用DH系的所有加密算法,要么干脆直接先用明文协议开发,完成后再接入SSL。