HTTPS 为何安全?
HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少
HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL
HTTP 与 HTTPS 区别
- http明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。
- 使用https 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,免费且好用的证书,[Let’s Encrypt](Let’s Encrypt - Free SSL/TLS Certificates),但证书的有效期只要3个月。好用指的是它的申请方式和浏览器的支持程度。
- http 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。
- http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
- https 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP 要更耗费服务器资源。
客户端,服务端,CA机构
证书类型
DV类型证书:中文全称是域名验证型证书,证书审核方式为通过验证域名所有权即可签发证书。此类型证书适合个人和小微企业申请,价格较低,申请快捷,但是证书中无法显示企业信息,安全性较差。在浏览器中显示锁型标志。
**OV类型证书:**中文全称是企业验证型证书,证书审核方式为通过验证域名所有权和申请企业的真实身份信息才能签发证书。目前OV类型证书是全球运用最广,兼容性最好的证书类型。此证书类型适合中型企业和互联网业务申请。在浏览器中显示锁型标志,并能通过点击查看到企业相关信息。支持ECC高安全强度加密算法,加密数据更加安全,加密性能更高。
**EV类型证书:**中文全称是增强验证型证书,证书审核级别为所有类型最严格验证方式,在OV类型的验证基础上额外验证其他企业的相关信息,比如银行开户许可证书。EV类型证书多使用于银行,金融,证券,支付等高安全标准行业。其在地址栏可以显示独特的EV绿色标识地址栏,最大程度的标识出网站的可信级别。支持ECC高安全强度加密算法,加密数据更加安全,加密性能更高。
如何模拟三者?
- 模拟CA机构
(1)创建CA证书私钥:
openssl genrsa -out root.key 1024
(2)创建Certificate Signing Request文件:
openssl req -new -out root.csr -key root.key
Country Name (2 letter code) [XX]:cn
State or Province Name (full name) []:sichuan
Locality Name (eg, city) [Default City]:chengdu
Organization Name (eg, company) [Default Company Ltd]:alibaba
Organizational Unit Name (eg, section) []:iflytek
Common Name (eg, your name or your servers hostname) []:root
Email Address []:chengzhang19@iflytek.com
A challenge password []:
An optional company name []:
(3)自签CA证书:
openssl x509 -req -in root.csr -out root.crt -signkey root.key -CAcreateserial -days 3650
-
模拟服务端
1)生成服务器端证书私钥: openssl genrsa -out server.key 1024 (2) 生成服务器Certificate Signing Request文件 openssl req -new -out server.csr -key server.key # 会有相同提示 (3) 生成服务器端公钥证书 openssl x509 -req -in server.csr -out server.crt -signkey server.key -CA root.crt -CAkey root.key -CAcreateserial -days 3650
-
模拟客户端
(1)生成客户端证书秘钥: openssl genrsa -out client.key 1024 (2) 生成客户端Certificate Signing Request文件 openssl req -new -out client.csr -key client.key # 会有相同提示 (3) 生客户端证书 openssl x509 -req -in client.csr -out client.crt -signkey client.key -CA root.crt -CAkey root.key -CAcreateserial -days 3650
到此处我们需要的所有证书都创建完毕了。
文件说明
- *.key: 私钥文件
- *.csr: 签名请求文件
- *.crt: 证书文件
TCP 三次握手
在讲解认证之前,我们先了解三次握手
- TCP Out-of-Order 说明网络存在较大的TCP乱序或丢包。
- TCP Dup ACK 当网络中存在乱序或者丢包时,将会导致接收端接收到的seq number不连续。此时接收端会向发送端回复重复ack,ack值为期望收到的下一个seq number。重复ack数大于等于3次将会触发快速重传。
- TCP Retramsmission TCP重传,当抓到2次同一包数据时,wireshark判断发生了重传,同时wireshark没有抓到初传包的反馈ack,因此,wireshark判定重传有效,标记为TCP Retransmission。
HTTPS 单向认证
sequenceDiagram
alt 单向认证流程
客户端 -->>+ 服务端: 1.发送SSL协议版本号、加密算法种类、随机数等信息
服务端 -->>+ 客户端 : 2.返回SSL协议版本号、加密算法种类、公钥证书:server.crt
客户端 ->> 客户端 : 3.解密server.crt,验证证书合法性,从证书中拿到公钥
客户端 -->>+ 服务端: 4.发送自己所能支持的对称加密方案,供服务器端进行选择
服务端 ->> 服务端 : 5.选择加密程度最高的加密方式
服务端 -> 客户端: 6.选择好的加密方案通过明文方式返回给客户端
客户端 -->>+ 服务端: 7.使用该加密方式生成产生随机码X,使用服务端返回的公钥进行加密,将加密后的随机码发送至服务器
服务端 ->> 服务端 : 8.使用自己的私钥进行解密,获取对称加密密钥
服务端 -> 客户端: 9.双方使用随机数X作为密钥进行https通信
end
单向认证抓包
详细分析
-
Client Hello
- TLS的版本
- 随机数:这个是用来生成最后加密密钥的影响因子之一,包含两部分:时间戳(4-Bytes)和随机数(28-Bytes),暂时记为random1。
- session-id:用来表明一次会话,第一次建立没有。如果以前建立过,直接传过去。
- 加密算法套装列表:客户端支持的加密-签名算法的列表,让服务器去选择。
- 压缩算法:似乎一般都不用
- 扩展字段:比如密码交换算法的参数、请求主机的名字等等
-
Server Hello
- 据客户端支持的SSL/TLS协议版本,和自己的比较确定使用的SSL/TLS协议版本,确定加密套件,压缩算法
- 产生了一个随机数,这里记为random2。注意,至此客户端和服务端都拥有了两个随机数(random1+random2),这两个随机数会在后续生成对称秘钥时会用到。
-
Server -> Client
这次会传输三个部分内容,Certificate, Server Key Exchange, Server Hello Done
-
Certificate:这里主要就是把证书发送给Client,客户端拿到证书后就可以进行验证,同时获取到公钥,用于后面random3的加密。
-
Server Key Exchange:这个消息是用来发送密钥交换算法相关参数和数据的。就是根据密钥交换算法的不同,传递的参数也是不同的。 常用的密钥交换算法:RSA、DH(Diffie-Hellman)、ECDH(Ellipticcurve Diffie–Hellman)。
-
Server Hello Done: 表示服务器通讯完毕
-
-
Client -> Server
这次会传输三个部分内容,Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message- Client Key Exchange: 客户端会再生成一个随机数random3。然后使用服务端传来的公钥进行加密得到密文PreMaster Key。服务端收到这个值后,使用私钥进行解密,得到Random3。这样客户端和服务端就都拥有了random1、random2和random3。这样两边的秘钥就协商好了。后面数据传输就可以用协商好的秘钥进行加密和解密
- Change Cipher Spec:编码改变通知。这一步是客户端通知服务端后面再发送的消息都会使用前面协商出来的秘钥加密了,是一条事件消息。
- Encrypted Handshake Message:Client Finish 消息,客户端将前面的握手消息生成摘要再用协商好的秘钥加密,这是客户端发出的第一条加密消息。服务端接收后会用秘钥解密,能解出来说明前面协商出来的秘钥是一致的。
-
Server -> Client
这次会传输三个部分内容,New Session Ticket, Change Cipher Spec, Encrypted Handshake Message
- New Session Ticket:包含了一个加密通信所需要的信息,这些数据采用一个只有服务器知道的密钥进行加密。目标是消除服务器需要维护每个客户端的会话状态缓存的要求
- Change Cipher Spec:编码改变通知。这一步是服务端通知客户端后面再发送的消息都会使用加密,也是一条事件消息。
- Encrypted Handshake Message: Server Finish 消息,服务端也会将握手过程的消息生成摘要再用秘钥加密,这是服务端发出的第一条加密消息。客户端接收后会用秘钥解密,能解出来说明协商的秘钥是一致的。
HTTPS 双向认证
sequenceDiagram
alt 单向认证流程
客户端 -->>+ 服务端: 1.发送SSL协议版本号、加密算法种类、随机数等信息
服务端 -->>+ 客户端 : 2.返回SSL协议版本号、加密算法种类、公钥证书:server.crt
客户端 ->> 客户端 : 3.解密server.crt,验证证书合法性,从证书中拿到公钥
客户端 -->>+ 服务端: 4.将自己的证书client.crt发送至服务端
服务端 ->> 服务端 : 5.验证客户端的证书client.crt,通过验证后,会获得客户端的公钥
客户端 -->>+ 服务端: 6.发送自己所能支持的对称加密方案,供服务器端进行选择
服务端 ->> 服务端 : 7.选择加密程度最高的加密方式
服务端 -> 客户端: 8.选择好的加密方案使用客户端公钥进行加密后返回给客户端
客户端 -->>+ 服务端: 9.使用client.key私钥进行解密,得到加密方式,产生随机码X,使用server.crt公钥进行加密后,发送给服务端
服务端 ->> 服务端 : 10.服务端使用server.key私钥对进行解密,获得对称加密的密钥
服务端 -> 客户端: 11.双方使用随机数X作为密钥进行https通信
end
双向认证抓包
如何验证证书合法的
浏览器需要验证SSL证书的5个方面:
-
验证浏览器中“受信任的根证书颁发机构”是否存在颁发该SSL证书的机构。
-
检查证书有没有被证书颁发机构吊销。
-
验证该网站的SSL证书是否过期。
-
审核该SSL证书的网站的域名是否与证书中的域名一致。
-
该网站有没有被列入欺诈网站黑名单。
**注意:**中间证书和根证书统称为证书链,如果我们在部署证书时,仅导入了用户证书,那么PC端访问网站是没有问题的,因为PC浏览器内置绝大部分CA的证书链,会自动补全。如果是移动端访问,如大部分的手机浏览器,那么就会提示不安全,因为大部分的手机浏览器并不会内置证书链,所以无法识别用户证书,也就会把网站标记为不安全。所以切记,部署证书是一定要安装证书链。
wireshark解析HTTPS数据包
Using the (Pre)-Master-Secret
The master secret enables TLS decryption in Wireshark and can be supplied via the Key Log File. The pre-master secret is the result from the key exchange and can be converted to a master secret by Wireshark. This pre-master secret can be obtained when a RSA private key is provided and a RSA key exchange is in use.
Step-by-step instructions to decrypt TLS traffic from Chrome or Firefox in Wireshark:
- Close the browser completely (check your task manager just to be sure).
- Set environment variable
SSLKEYLOGFILE
to the absolute path of a writable file. - Start the browser.
- Verify that the location from step 2 is created.
- In Wireshark, go to Preferences -> Protocols -> TLS, and change the (Pre)-Master-Secret log filename preference to the path from step 2.
- Start the Wireshark capture.
- Open a website, for example https://www.wireshark.org/
- Check that the decrypted data is visible. For example, using the
tls and (http or http2)
filter.
For Windows, an environment variable can be set globally as described in this walkthrough, but this is not recommended since it is easy to forget about and may be a security issue since it allows decryption of all your TLS traffic. A better way to set the environment variable is via a batch file. Create a file start-fx.cmd
with:
@echo off
set SSLKEYLOGFILE=%USERPROFILE%\Desktop\keylogfile.txt
start firefox
Change the SSLKEYLOGFILE
path as needed, and replace firefox
with chrome
for Google Chrome. This mechanism currently (2019) does not work for Safari, Microsoft Edge, and others since their TLS libraries (Microsoft SChannel/Apple SecureTransport) do not support this mechanism. This mechanism works for applications other than web browsers as well, but it dependent on the TLS library used by the application.