重温HTTPS
在开始之前,我们需要再次捋清整个HTTPS握手的流程,思考下面几个问题,你是否完全懂整个流程?
A:HTTPS中共用到了两种加密,这两种加密的作用和关系是什么?
Q:非对称加密只是为了加密对称加密的密钥(还起了身份认证功能),而对称加密用于加密真正的http数据。
A:非对称加密和对称加密的密钥分别是由谁形成的?
Q:首先,对称加密的密钥是由客户端来随机生成的。而非对称加密的密钥则需要考虑密钥协商算法了,在DHE/ECDHE等算法中,非对称加密的公私钥是临时生成的,私钥保存在服务端上,公钥则由服务端发送给客户端。而其他密钥协商算法如RSA、DH_DSS、DH_RSA等,则公钥使用的就是证书上的公钥。私钥就是服务端上证书的私钥。
A:证书在整个HTTPS过程中起了什么作用?
Q:在通常的HTTPS握手中,证书其实只是起到了认证的作用,浏览器通过预存的各大CA的公钥去解密证书的内容,判断目标是否为真实目标,而不是伪造的目标(也就是说,证书中的公私钥并不会用于后续的密钥协商)。当然对于RSA和DH密钥协商算法,证书的公钥就被用于加密预主密钥。
A:在私钥不泄露的前提下,客户端和服务端怎么保证对称加密的密钥不会被破解?
Q:首先我们需要知道公钥加密只能私钥解密,并且在HTTPS的过程中,服务端的私钥是不会返回给客户端的。
而这个对称加密的密钥是由客户端随机生成的,客户端使用服务端提供的公钥去加密这个私钥,返回给服务端。服务端接收后,再使用私钥去解密。因此在私钥不泄露的情况下,对称加密的密钥也自然不会被破解。
A:客户端和服务端怎么保证它们进行密钥协商交换后,大家得到的(对称)密钥是一致的。
Q:这里还是和上一个问题一样,在密钥交换过程中,客户端并非只是单单只把加密后的密钥发送给服务端。客户端和服务端都会在密钥协商完成后,将之前自己发过的包和收到的包做一个hash杂凑再用对称密钥进行加密发送给对方。
对方在接收到后,使用协商好的密钥去解密数据。一致则代表大家密钥协商成功,开始数据传输。
反复思考上面的几个问题,理解后我们不难得以下结论;
想要解密流量,要么获取非对称加密的私钥,要么获取对称加密的密钥。
-
私钥是只在服务端上的,根据不同的密钥协商算法,这个私钥要么就是证书的私钥,要么是临时生成的保存在服务端缓存中的。
-
对称加密的密钥即在客户端也在服务端上。但都只是在缓存中。
也就是说,我们破解流量就可以细分为以下几种场景:
①客户端权限:读取缓存中的加密密钥,一步到位。(部分使用openssl和nss库的应用可行)
②服务端权限:读取缓存中的对称加密密钥或者私钥(需要逆向服务器实现,工作量太大)再或者修修改服务器的首先密钥交换协议,使用我们或者它原本的证书私钥进行加解密。(优选)
③没有权限,只有流量包,和对应的私钥。直接使用私钥加解密。(得看密钥交换协议用的是临时的还是其他)
客户端权限
Chrome和Firefox会使用的NSS库来处理TLS。而NSS(OpenSSL也可以) 可以写入密钥日志,以便外部程序可以解密 TLS 连接。通过设置环境变量SSLKEYLOGFILE,将其指向一个可写入的文件。这样浏览器在启动时就会检查这个环境变量,如果存在的话,它会向指定的文件写入访问HTTPS站点时使用的密钥。我们只需要把这个文件给导入到wireshark,就可以解密流量了。
将该文件加载到wireshark中,waireshark就会自动解密,获取到HTTP流量
编辑->首选项->Protocols->TLS
导入sslkeylog后,流量成功破解。
服务端权限(使用证书私钥直接解密)
服务端并不像客户端有浏览器输出sshkeylog,我们除非逆向服务器,不然密钥只出现在缓存中。
但是我们可以让服务器不走临时的密钥交换协议。
当然目前服务器默认都会选择ECDHE模式。因此我们要修改服务器选项,让服务器关闭临时交换算法来实现,这里用nginx服务器实现。
nginx配置SSL
检查环境是否支持SSL
nginx -V #检查是否存在ssl模块,没有则需要重新build nginx
生成自签名SSL证书
这里使用keytools生成自签名证书,再用openssl转换格式
修改nginx配置文件,加载证书
在HTTP内新增一个server
server {
listen 80;
listen 443 ssl; # 监听443端口, 开启ssl(必须)
server_name domain.com;
ssl_certificate /root/cer.crt; #公钥(只能是文本格式的)
ssl_certificate_key /root/private.key; #私钥(也要文本格式)
# 协议优化(可选,优化https协议,增强安全性)
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
# ssl_prefer_server_ciphers on;
# ssl_session_cache shared:SSL:10m;
# ssl_session_timeout 10m;
root /var/www/html;
location / {
index index.html index.htm;
}
}
最终实现效果如下。
nginx -s reload
修改服务器支持的加密套件
nginx中,ssl_ciphers配置项的可选值由openssl的ciphers定义
openssl ciphers -v #输出当前服务器支持的加密套件,不加-v则是不换行输出。
先获取当前服务器支持的套件,然后copy到vscode中,使用正则去掉所有的临时密
openssl ciphers #输出不换行的加密套件
(DHE|ECDHE)-[^:]{1,}: #VScode中去掉临时密钥交换算法的正则
然后修改nginx的配置文件,添加ssl_ciphers 即可
流量解密
这里已经很明了了,直接把服务器证书的私钥给导入wireshark就能读到明文数据了。
nps流量解密
直接导入证书就完事了,在隧道传输流量的时候用的是TLS协议,和https是一样的
关于我们
原文始发于微信公众号(风起专注的安全小屋):非对称密码-使用私钥破解https流量
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论