文章目录
一、实验环境
操作系统:macOS Ventura 13.0.1
Apache:Apache/2.4.54 (Unix),此版本为mac系统默认自带的Apache服务器版本
Wireshark:Wireshark 4.0.2
二、为 Apache 服务器启用 SSL
1.获取 SSL 证书
SSL证书可以通过 阿里云SSL证书服务 免费购买,但购买后的证书还没有提交到CA中心,需要填写域名、申请人等信息后提交CA中心,待验证通过后签发证书,签发过程大概几分钟就能完成。
证书签发完成后按Apache支持的crt格式下载即可,解压后的文件夹中有3个文件:
- 证书文件:以.crt为后缀或文件类型。
- 证书链文件:以.crt为后缀或文件类型。
- 密钥文件:以.key为后缀或文件类型。
当然也可以借助于openssl工具在本地生成自签名的SSL证书,但过程较为繁琐而且容易出现问题。
2.修改 httpd.conf 配置文件
在Apache配置文件目录 /private/etc/apache2
下,打开 httpd.conf
文件,进行如下修改:
# LoadModule ssl_module modules/mod_ssl.so # 删除行首的配置语句注释符号“#”加载mod_ssl.so模块启用SSL服务,Apache默认不启用该模块。
# Include conf/extra/httpd-ssl.conf # 删除行首的配置语句注释符号“#”。
3.修改 httpd-ssl.conf 配置文件
在 /private/etc/apache2/extra/
目录下,打开 httpd-ssl.conf
文件,在文件中添加以下内容,并按照下文中注释内容进行配置:
<VirtualHost *:443>
ServerName # 修改为申请证书时绑定的域名。
DocumentRoot "/Library/WebServer/Documents"
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3 # 添加SSL协议支持协议,去掉不安全的协议。
SSLCipherSuite HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM
SSLHonorCipherOrder on
SSLCertificateFile /private/etc/apache2/ssl/9042749_www.atreus.ink_public.crt # 替换成证书文件名。
SSLCertificateKeyFile /private/etc/apache2/ssl/9042749_www.atreus.ink.key # 替换成证书的密钥文件名。
SSLCertificateChainFile /private/etc/apache2/ssl/9042749_www.atreus.ink_chain.crt # 替换成证书链文件名
</VirtualHost>
4.启动 Apache 服务
通过命令 sudo apachectl start
即可启动Apache服务,通过 https:// + IP
即可以SSL访问主页,默认主页位于 /Library/WebServer/Documents
路径下,可自行修改。
如果启动失败或页面无法访问,可以查看 /private/var/log/apache2/error_log
路径下的错误日志进行排查。
三、SSL/TLS 工作过程分析
上图为通过Wireshark抓包的数据,客户端与服务器两台主机位于同一局域网中,其中 192.168.0.36:53249
为客户端套接字, 192.168.0.7:443
为服务器套接字。
最开始的三条数据包实现了TCP的三次握手,这表明TLS以TCP作为基础。其中 Seq
为序号,Ack
为确认号,Win
为窗口大小(现在允许对方发送的数据量),Len
为TCP数据部分长度,MSS
为最大报文段长度,WS
表示窗口的放大倍数,SACK_PERM
表示通信双方均支持SACK机制。
53294 -> 443 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
443 -> 53294 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1460 WS=64 SACK_PERM
53294 -> 443 [ACK] Seq=1 Ack=1 Win=131328 Len=0
TLS握手与通信阶段报文如下所示,总体上可以分为七步:
192.168.0.36 -> 192.168.0.7 TLSv1.2 Client Hello
192.168.0.7 -> 192.168.0.36 TLSv1.2 Server Hello
192.168.0.7 -> 192.168.0.36 TLSv1.2 Certificate
192.168.0.7 -> 192.168.0.36 TLSv1.2 Server Key Exchange, Server Hello Done
192.168.0.36 -> 192.168.0.7 TLSv1.2 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
192.168.0.7 -> 192.168.0.36 TLSv1.2 New Session Ticket, Change Cipher Spec, Encrypted Handshake Message
192.168.0.36 -> 192.168.0.7 TLSv1.2 Application Data
第一步,Client Hello
。浏览器给出协议版本号、客户端生成的随机数、客户端支持的加密套件和客户端支持的压缩算法。这一步客户端有可能连续发送多个除了端口号和随机数其他信息均一致的 Client Hello
包,目的是避免超时重传影响用户体验。
第二步,Server Hello
。服务器会确认双方最终使用的TLS版本号、加密套件以及其它一些必要信息,同时还会发送一个服务器生成的随机数,这个随机数稍后会用于生成对话密钥。其中 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
表明采用了TLS协议和ECDHE交换算法,并且是RSA公钥加密。
第三步,Certificate
。服务器发送证书给客户端,该证书用于向客户端确认服务器的身份。可以看到,我这里证书申请时用的是域名为 www.atreus.ink,和服务器实际域名并不匹配。
第四步,Server Key Exchange, Server Hello Done
。服务器会发送给客户端Diffie-Hellman算法相关参数,如下图中的pubkey参数,这个参数需要通过网络传给浏览器,但即使它被截取也不会影响安全性。通过这些参数后期客户端可以算出会话密钥,传递完参数之后,服务器会告诉客户端 Server Hello
结束了。
第五步,Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
。浏览器收到服务器发来的 Certificate
包之后,运行Diffie-Hellman算法生成一个pubkey,这个pubkey也被称为预备-主密钥,然后这个pubkey会被发送给服务器,服务器结合自己的私钥解出这个预备-主密钥的信息,得到第三个随机数。基于这三个随机数,服务器和客户算就可以生成一个一样的会话密钥用于通信。
第六步,New Session Ticket, Change Cipher Spec, Encrypted Handshake Message
。前五步完成后基本上可以说TLS的握手阶段已经完成了,但是服务器还会发送一个 Session Ticket
给浏览器,这个 Session Ticket
包含了它的生命周期(7200s)以及它的id等信息,有了这个 Session Ticket
之后,如果出于某种原因对话中断,就需要重新握手,而此时客户端只需发送一个服务器在上一次对话中发送过来的 Session Ticket
就可以继续使用上一次连接了。这个 Session Ticket
是加密的,只有服务器才能解密,其中包括本次对话的对话密钥和加密方法等信息。
第七步,Application Data
。在TLS握手成功且 Session Ticket
传递完毕后服务器与客户端就可以进行通信了。