对称加密与非对称加密:你手里的两把钥匙
今天咱们来聊聊最核心的加密原理。说实话,很多新人一上来就被各种数学公式吓住了。我觉得没必要。你只需要搞懂两个问题:用什么锁?怎么管钥匙?
对称加密:一把钥匙开一把锁
对称加密,说白了就是加密和解密用的是同一把钥匙。你想想看,我们锁门的时候,插进去和拔出来用的都是同一把钥匙。AES、ChaCha20、SM4这些算法都是这个路子。
我记得早年做嵌入式项目,设备资源紧张,只能用对称加密。数据量上来之后,性能差距立刻就能看出来。AES-128-GCM在硬件加速下,跑1Gbps几乎不占CPU。嗯,这里要注意:AES有三种密钥长度——128、192、256。大家别觉得越长越好,128位在可见未来完全够用。
| 对称算法 | 密钥长度 | 分组大小 | TLS常用模式 | 我的评价 |
|---|---|---|---|---|
| AES | 128/192/256位 | 128位 | GCM、CCM | 硬件加速后极快,主流选择 |
| ChaCha20 | 256位 | —(流密码) | Poly1305 | 无硬件加速时很快,移动端优选 |
| SM4 | 128位 | 128位 | GCM、CBC | 国密标准,国内合规场景必用 |
核心避坑点:对称加密最大的痛点不是算法本身,而是密钥分发。你俩得先商量好一个共同密码。可如果中间有人在听,这个商量过程本身就是问题。
为什么对称加密的密钥管理这么头疼?
我接过一个审计项目,对方把所有设备的对称密钥硬编码在配置文件中,而且所有设备用同一个密钥。当时我就说,这跟没上锁有什么区别?
对称密钥管理的核心难题有这几个:
- 密钥分发:你得保证把密钥安全地从A送到B。走网络怕被截,走人工又容易泄密。
- 密钥存储:设备坏了,密钥跟着丢。你想想,所有加密数据就再也解不开了。
- 密钥轮换:用久了不换,攻击者可以慢慢猜。我建议至少每24小时轮换一次临时会话密钥。
- 多对多组合:一个系统里有1000个节点,如果两两之间都要共享一个对称密钥,那就得管理将近50万个密钥。你算算这维护成本。
曾经踩过的坑:我曾经遇到过一家公司的H SM设备,每次断电重启后密钥自动清空,但工程师不知道这一点,结果大批量加密数据在灾备恢复后全部无法读取。所以,密钥的生命周期管理——从生成、使用到备份——一定不能有断点。
非对称加密:一对钥匙,各有分工
非对称加密就聪明多了。它用数学上的「单向陷门函数」——正向做很容易,反向做几乎不可能。一个公钥拿来加密,私钥才能解开;或者反过来,私钥签名,公钥验证。
个人觉得,RSA和ECC(椭圆曲线,比如E CDH、ECDSA)是现在TLS里最常用的两种。RSA基于大整数分解,ECC基于椭圆曲线离散对数。你可能会问:谁更好?
| 安全等级 | RSA密钥长度 | ECC密钥长度 | 实际意义 |
|---|---|---|---|
| ~80位对称安全性 | 1024位 | 160位 | 已废弃,千万别用 |
| ~112位对称安全性 | 2048位 | 224位 | 最低要求,勉强够用 |
| ~128位对称安全性 | 3072位 | 256位 | 当前推荐标准 |
| ~192位对称安全性 | 7680位 | 384位 | 对高安全场景,性能牺牲明显 |
| ~256位对称安全性 | 15360位 | 521位 | 后量子时代到时可能要换别的 |
从表上能看得很清楚,ECC用短得多的密钥,实现了差不多的安全程度。我记得带一个金融安全项目,客户执意要RSA-1024,我硬是让他们升级到2048位。后来爆出的针对1024位的攻击,证明了当时的决定是对的。
为什么我们需要混合起来用?
你可能会说:既然非对称加密不用提前共享密钥,那直接用非对称不就完了?说实话,非对称加密太慢了。RSA-2048在TLS握手阶段还好,但用它加密整条会话数据完全不现实。
所以TLS采用混合加密策略:
- 握手阶段用非对称加密:通过证书验证身份,协商出一把临时的对称密钥。
- 数据传输阶段用对称加密:用刚谈好的对称密钥,以极高的速度加密每条消息。
为什么这么做?
- 非对称加密解决了密钥分发的安全问题。你不必预先知道对方的对称密钥。
- 对称加密解决了性能问题。几百兆的数据,一秒钟就能加解密完。
- 每次会话都生成独立的临时密钥——这叫前向安全性。就算这次会话的密钥被泄露,以前的会话数据还是安全的。
密钥封装与密钥派生
这里有两个概念容易被混淆,我拿出来单独讲。
密钥封装:用接收者的公钥,把一个对称密钥「包起来」传过去。最典型的就是RSA密钥交换。你把AES密钥用RSA公钥加密,只有持有私钥的人才能解包。
密钥派生:通过一个共享的秘密(比如DH协商出的共享值),用一系列哈希运算,生成多个不同的对称密钥。TLS 1.3里用了HKDF(HMAC-based Key Derivation Function)来做这件事。
你想想,在一次TLS握手里,我们要同时用到会话加密密钥、会话认证密钥、初始化向量。如果只靠一个原始共享秘密,那太脆弱了。通过密钥派生,我们能把一个种子衍生出多把独立的功能性密钥。
我个人的工程建议:在实现密钥派生时,context参数一定要体现具体的流程阶段。比如TLS握手阶段用的上下文是"tls1.3 session key",而恢复密钥用的是"tls1.3 resumption master key"。这样做的好处是,不同阶段的密钥不会被混淆使用,降低了逻辑漏洞的概率。
对称+非对称:TLS的整体密钥流程
下面这张图把整个密钥管理的层级关系梳理清楚了。你看了一目了然。
从图中你可以看出,整个流程是非对称加密「协商」出共享秘密,然后密钥派生层从共享秘密「衍生」出多个对称密钥,最后对称加密层用这些密钥保护实际数据。环环相扣,缺一不可。
总结要点
- 对称加密快,但密钥分发难。你要管好那把「共享钥匙」。
- 非对称加密解决了密钥分发问题,但速度太慢,不能用于批量数据。
- 混合加密是TLS的聪明选择:非对称握手 + 对称传输。
- 密钥派生(HKDF)把共享秘密变成多把功能独立的对称密钥。
- 每次握手都生成新临时密钥,这是实现前向安全的前提。
你理解了这些东西,后面再深入TLS握手协议的细节时就不会觉得云里雾里了。嗯,差不多就是这些。记住,密钥管理的本质,就是搞清楚「哪把钥匙给谁用、用在哪、用多久」这三个问题。