SSL/TLS 原理详解
说实话,SSL/TLS 这套东西刚学时我也觉得绕。但干过几回 HTTPS 接入后,你会发现它本质上就靠四个东西撑起来:对称加密、非对称加密、哈希、数字签名。再加上 PKI 这个信任骨架,整个安全通道就立住了。下面我按自己理解拆开讲,都是实践里常碰到的点。
对称加密 vs 非对称加密
对称加密,说白了就是加密和解密用同一把钥匙。你最熟的可能是 AES,还有 3DES、ChaCha20。优点就一个字——快。我在项目里测过,软件 AES-128 加解密 1KB 数据也就几微秒,扛大流量完全没问题。
非对称加密呢,加密和解密用不同的钥匙(公钥 + 私钥)。典型的有 RSA、ECC(椭圆曲线)。私钥只有自己留着,公钥随便发。这样别人用公钥加密的数据,只有私钥持有者能解开。但代价是慢,非常慢。RSA-2048 做一次私钥操作比 AES 慢上千倍。所以实际场景里,非对称加密只用来交换一个临时生成的对称密钥,后面通信用对称加密。
| 特性 | 对称加密 | 非对称加密 |
|---|---|---|
| 密钥数量 | 1 个 | 2 个(公钥 + 私钥) |
| 典型算法 | AES, ChaCha20, 3DES | RSA, ECDSA, Ed25519 |
| 速度 | 极快 | 慢(千倍级差距) |
| 适用场景 | 大量数据加密(传输内容) | 密钥交换、数字签名 |
| 密钥分发 | 需安全通道分发 | 公钥可明文分发 |
哈希函数:数据指纹
哈希函数能把任意长度的数据“压缩”成固定长度的摘要。而且不可逆、防碰撞。说人话:你就算只改了一个比特,整个摘要都会变。SHA-256 现在用得最多,我还见过老系统用 SHA-1 的(早该换了)。
哈希在 TLS 里有两大作用:一是校验握手消息完整性,二是配合数字签名做身份验证。嗯,这里要注意,哈希本身不防篡改——攻击者可以同时改数据和摘要。所以必须和签名配合。
数字签名:谁说的,没改过
数字签名解决两个问题:身份确认和内容防篡改。流程其实很简单:发送方先用哈希算出消息摘要,再用自己的私钥加密这个摘要(这就是签名)。接收方用发送方的公钥解开签名,得到摘要A;再自己算一次消息摘要B,对比A和B。一样就说明是本人发的,而且内容没动过。
我踩过一个坑:以前做 SSl Offloading 时,后端服务器用的自签名证书。我图省事在代码里信任了所有证书,结果被中间人攻击搞了一次。从那以后,我再也不敢跳过证书校验了。
PKI 体系:信任的骨架
公钥是公开的,但你凭什么相信一个公钥确实属于对面那个人?这就是 PKI(公钥基础设施)的活儿。CA(证书颁发机构)是个信用中介,它用自己的私钥给你签发一张数字证书,把你的公钥、域名、组织信息绑在一起。
浏览器内置了一堆根证书(Root CA)。你访问一个 HTTPS 站点时,服务器发来证书,浏览器会沿证书链向上查,直到找到一个信任的根证书。如果整个链都能验过签名,那这个证书就是可信的。我建议做负载均衡时,优先用公认的 CA 签发证书,别搞自签名——除非你完全控制客户端,比如内部微服务间通信。
一套图的脉络
下面这张图把上面四个概念串在一起了。你如果理解这个流程,TLS 握手基本就通了。
避坑指南
- 不要用太弱的对称加密套件。 比如 RC4、DES 早该退役了。我曾经在旧 Nginx 配置里发现默认启用了 RC4,吓得赶紧改掉。现在至少用 AES-128-GCM 或 ChaCha20。
- 证书链要传完整。 很多新手只配了服务器证书,中间证书没带。这样某些客户端(比如 Android 低版本)会因为缺链而拒绝连接。我在线上就踩过,排查了半天。
- 私钥权限必须严格。 私钥文件最好 600 权限,属主只给需要读的进程(比如 nginx 的 worker)。我曾经见过开发直接把私钥放到 git 仓库里……嗯,这种事千万别干。
好了,这一节就到这里。理解了这些基础,后面讲 SSL Offloading 具体配置时,你就知道为什么要在负载均衡器上解密、为什么需要传递客户端证书、以及怎么保证后端通信的安全了。自己动手抓个 TLS 握手包看看,比光看文档印象深得多。