wireshark抓取https包

背景

在自己的路由器上实现了自己签名的证书,可以搭建https的网站了.
但是还想用wireshark来具体看看效果.

方法总结

SSL握手过程中,客户端依靠服务器的公钥,服务器依靠自己的私钥,
会协商一个通信用的对称加密密钥,
想要明文查看https包,就需要提前将一些信息提供给wireshark,
然后让wireshark也监听到对称加密的密钥.
因此目前,网络上主要有两种方法

  1. 直接将服务器的私钥交给wireshark(即使可行也只适合自己搭建的网站)
  2. 将浏览器保存的sslkeylog交给wireshark

而wireshark官方也更倾向于推荐第二种方法.

私钥法

找来服务器的私钥,比如 server.key.
在wireshark的设置(编辑->首选项->RSA密钥)中,添加新的私钥即可.

目前的问题

传统的协商一个对称密钥的方式其实有缺点,如果保存了所有数据包,
日后一旦获得私钥,那么数据就不再安全.
为了解决这个前向安全的问题,
有人提出服务器的私钥暂时只用来做身份认证,
协商对称密钥时用一个临时的数据,
即使服务器的私钥泄露也不会有数据安全的问题.
目前这种实践方式非常普遍,nginx默认也使用这种更加安全的方式.
因此即使将私钥交给wireshark,在默认的配置下也毫无用处.
如果更改了nginx的配置使用了较为不安全的key exchange方法,
网站本身会不安全,并且浏览器也会嫌弃等级太低而拒绝打开.

log法

  1. 配置sslkeylog

    1
    2
    3
    4
    5
    # 1. 配置环境变量
    export SSLKEYLOGFILE=$HOME/sslkeylog.log
    # 2. 为了让浏览器能够继承环境变量,在shell中启动之
    chromium https://example.org
    # 3. 在文件中会生成内容
  2. 配置wireshark
    编辑->首选项->Protocols->TLS
    在(Pre)-Master-Secret log filename处设置刚才的log文件
    为了应对可能的问题,一并指定TLS debug file的路径.

  3. 重新在shell中启动浏览器访问网站,即可抓包

    • sslkeylog文件是会变动的,即使有了内容,也不能利用shell外部打开的浏览器来抓包
    • 即使是通过shell打开浏览器也应确认在这之前该浏览器没有被打开

RSA,DH,DHE,ECDHE等

本身都是为了交换对称密钥时的一种方法.

RSA

C端使用S的公钥将预主密钥a加密并发送给S.(C发送一个Client key exchange报文)
S端使用S的私钥将预主密钥a解密.
问题:如果私钥泄露,就不再安全,成为前向(未来的某一天)不安全.

DHE

C端生成一个值Xa,却把q^Xa^ mod p的结果(起名Pa)发给S.(C发送Client key exchange)
S端生成一个值Xb,却也吧q^Xb^ mod p的结果(其名Pb)发给C.(S发送Server key exchange)
C端计算Sa=Pb^Xa^ mod p,S端计算Sb=Pa^Xb^ mod p,神奇的数学证明了Sa=Sb=a
优点:每条会话都有临时的Xa,Xb,一条会话被解密,其他会话还安全.
问题:计算量太过庞大,甚至比RSA还费事,耗费CPU是小事,网站卡顿是大事

ECDHE

不再使用大数的Xa^p^,转而使用一种性能更好的 椭圆曲线 的算法.
问题:由于比较新,暂时没有太多实践来验证与DHE有同等的安全能力

ECDH

E本身代表临时,
C端使用随机数Xa,计算成Pa发送给S端,(C发送一个Client key exchange报文)
S端省事直接使用公钥中作为Pb,自己的私钥作为Xb(S已经在certificate报文中发送过,不必)
C端计算Sa=f(Pb,Xa),S端计算Sb=f(Pa,Xb).
问题:由于需要直接将公钥作为Pb,公钥只能包含在ECC证书中.另外也依然有RSA泄露后就不再安全的问题.

nginx的配置

nginx可以配置的是 ssl_ciphers 字段,该字段翻译作加密套件,其实是众多过程中加密方法的组合.
使用

1
openssl ciphers -V |column -t

可以看到一些可用的加密套件
Kx = Key Exchange
Au = Authentication
Enc = Encrypt
Mac = Message Authentication Code
然而目前TLSv1.2的协议中,Kx=RSA的算法,浏览器认为安全性太差.
其他一些Kx=DH/RSA的拳法,浏览器有的还不支持.
因此修改 ssl_ciphers 字段并非一个好主意.不指定该字段以使用默认值就好.

参考

  1. wireshark明文查看https的方式
  2. 官方推荐key log文件的e房产
  3. DHE解释