打开浏览器,地址栏那把锁亮起来的时候,多数人默认"安全了"。但很少有人追问一句:这把锁到底锁住了谁?
答案可能让人不太舒服——普通TLS只证明了一件事:你连上的服务器是真的。反过来,服务器并不验证你是谁。客户端检查服务器的证书,服务器不检查客户端。这道单向门,就是TLS握手的默认状态。
![]()
要理解这道门怎么立起来的,得先分清三个经常被混着叫的名字。
SSL、TLS、OpenSSL,不是一回事
SSL和TLS都是协议,也就是客户端和服务器约定加密方式的一套规则。SSL先出现,后来TLS把它替换掉了。人们出于习惯还在说"SSL",但真正的SSL版本——SSL 2.0和SSL 3.0——已经被攻破,不再使用。今天任何被叫做"SSL"的连接,跑的几乎都是TLS。
那终端里敲的OpenSSL命令呢?它不是协议。它是一个实现了TLS(早年也实现过SSL)的库和命令行工具。名字从1990年代沿用至今,那时候TLS还不存在。现代OpenSSL默认协商TLS 1.2或TLS 1.3,已经完全不再支持SSL 2.0。
TLS本身也有多个版本。TLS 1.2至今仍然常见,TLS 1.3更新、更快。两者的共同点是:先协商出一个共享密钥,之后所有流量都用从它派生出的密钥加密。
mTLS补上的,是反方向的那次检查
普通TLS只证明服务器身份。客户端查服务器证书,服务器不查客户端。mTLS在另一个方向上加了一次证书检查:在任何数据流动之前,服务器也要先核实客户端是谁。这种双向检查,就是"mutual TLS"(双向TLS)这个名字的由来。
SSL/TLS协议的核心目标有三个:保证安全、保证数据完整性、避免中间人攻击。用大白话说,客户端和服务器在公网上对话时,中间的任何攻击者都不应该看到传输的数据是什么。
握手协议要完成的事,可以拆成四步:
- 交换hello消息,就算法和协议版本达成一致,并交换随机值。
- 交换必要的密码学参数(双方各自生成的随机值),让客户端和服务器能用Diffie-Hellman这类非对称加密算法生成premaster secret。
- 交换证书和密码学信息,让双方能够互相认证。
- 用对称加密算法,从premaster secret生成master secret。
握手逐条拆:从ClientHello到ServerKeyExchange
客户端第一次连接服务器时,必须把ClientHello作为第一条消息发出去。它提出自己支持的TLS版本、密码套件,并发送client_random——28字节的随机数加一个时间戳。
服务器收到后回ServerHello,从客户端给的列表里挑一个密码套件,发送server_random。如果session_id非空,服务器会去自己的会话缓存里找,复用已有会话。
密码套件不是单个算法,而是一组密钥交换算法的集合,比如RSA、DH_DSS、ECDH_ECDSA等。这些算法的作用,是让premaster secret在不经过公网明文传输的前提下完成交换。
接着服务器发送自己的证书链,通常包括叶子证书和中间证书。客户端之后会拿它和自己信任库里的内容做校验。
ServerKeyExchange只在DHE/ECDHE这类密码套件下出现。服务器发送自己的DH/ECDH参数(p和g)以及公钥值,并用与证书匹配的私钥签名。这个签名,正是用来证明DH参数确实来自服务器,而不是某个做中间人攻击的攻击者。静态RSA密钥交换没有这一步——那种情况下直接用服务器证书里的公钥。
这里的p是Diffie-Hellman运算使用的素数模数,g是生成元,Ys是服务器的DH公钥值(g^X mod p)。
最后一步CertificateRequest,只在需要mTLS时出现。服务器在这一步向客户端索要证书——那道单向门,到这里才被打开。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.