常见的加密场景(一)
加密解密
一、核心逻辑:锁和钥匙的比喻
加密和解密的核心逻辑其实很简单,就像一把锁和一把钥匙。
- 加密:你把一份机密文件放进一个保险箱,用锁锁上。这个过程就是加密。原始文件(明文)变成了保险箱里谁也看不懂的文件(密文)。
- 解密:接收方用正确的钥匙打开锁,从保险箱里取出文件阅读。这个过程就是解密。密文又变回了可读的明文。
这个比喻里的几个关键元素,就对应着密码学的核心概念。
二、什么是密钥?
密钥,就是上面比喻里的那把“钥匙”。
在数字世界,它不是一把物理钥匙,而是一串非常长的、复杂的数字(由0和1组成)。加密和解密算法都是公开的、标准的,就像世界上所有人都能买到同一个型号的保险箱。那么安全靠什么来保证呢?就靠你这把“钥匙”是独一无二的。
- 核心思想:算法的安全性不依赖于算法本身的保密,而依赖于密钥的保密。这就是著名的柯克霍夫原则。
三、对称加密:用同一把钥匙开锁
对称加密非常好理解:加密和解密使用同一把密钥。
- 谍战片比喻:这就是你提到的密码本!
- 明文: “明天上午十点火车站见面”
- 加密过程(密码本): 每个字对应一个数字或符号。比如“明”对应“A1”,“天”对应“A2”... 那么明文就变成了 “A1A2...”
- 密钥: 这本记录了文字和代码对应关系的密码本本身,就是密钥。
- 解密过程: 接收方收到“A1A2...”后,用同一本密码本反向查找,就得到了原始信息。
- 现代例子: AES(高级加密标准)就是一种非常常用的对称加密算法。你的Wi-Fi密码、对压缩文件加密码,很多时候用的都是对称加密。
- 优点: 速度快,效率高,适合加密大量数据(如整个硬盘、整个通信会话)。
- 缺点: 密钥分发问题。如何安全地把这把唯一的密钥交给对方?在谍战片里,传递密码本本身就是最危险、最容易出错的环节。数字世界也一样,如果通过网络发送密钥,可能被黑客截获。
四、非对称加密:配对的公钥锁和私钥匙
为了解决“密钥分发”这个致命弱点,非对称加密被发明了出来。它非常巧妙,使用一对 mathematically相关的密钥:一个公钥,一个私钥。
- 核心规则:
- 用公钥加密的内容,只能用对应的私钥解密。
- 用私钥加密(俗称“签名”)的内容,只能用对应的公钥解密(俗称“验证”)。
- 谍战片比喻(特制信箱):
- 公钥:就像一个特制的、只能锁上但不能打开的挂锁。你可以复制无数把这样的挂锁,发给世界上任何人。这个锁(公钥)不需要保密。
- 私钥:这是打开这个特制挂锁的唯一一把钥匙。你必须绝对秘密地保管好它,谁也不给。
- 工作流程(以发送密信为例):
- 我想给你发一封密信。我先问你要你的“特制挂锁”(公钥)。你大大方方地把锁给我(公钥是公开的)。
- 我把信放进保险箱,用你的公钥锁把箱子锁上。
- 现在,这个箱子世界上只有你能打开,因为只有你持有对应的私钥。连我自己都打不开了(因为我只有你的公钥,没有私钥)。
- 你把箱子运回来后,用自己的私钥打开锁,读取信件。
- 现代例子: RSA算法是最著名的非对称加密。它最重要的用途不是直接加密大量数据(因为速度慢),而是解决对称加密的“密钥分发”问题,以及用于数字签名。
- 混合加密系统(实际中最常用的方式):
- 小明想和大卫安全通信。
- 小明向大卫索要他的公钥。
- 小明随机生成一个临时密钥(这个是对称加密的密钥,比如AES密钥)。
- 小明用这个临时密钥加密真正的消息(因为对称加密速度快)。
- 小明再用大卫的公钥去加密那个临时密钥。
- 小明把【用临时密钥加密的密文】和【用大卫公钥加密过的临时密钥】一起发送给大卫。
- 大卫收到后,先用自己的私钥解密出那个临时密钥。
- 大卫再用这个临时密钥去解密真正的消息。
这个过程完美结合了两种加密的优点:非对称加密的安全密钥交换,和对称加密的高效数据加密。
HTTPS是如何实现的
太好了!这个问题正好能完美串联起我们刚才讨论的加密概念。HTTPS 的本质就是“HTTP over SSL/TLS”,即在普通的HTTP协议上加了一个强大的“安全层”。
这个安全层通过一套精密的“握手”协议,综合利用了非对称加密、对称加密和数字证书,最终实现了三大目标:
- 保密性:通信内容不被窃听。
- 完整性:通信内容不被篡改。
- 身份认证:你连接的是真正的目标网站,而非钓鱼网站。
下面我用一个经典的“访问网上银行”的例子,带你走一遍HTTPS的完整流程。
HTTPS连接建立的四步曲(简化版)
假设你在浏览器输入 https://www.mybank.com并回车。
第1步:打招呼与提供凭证(Client Hello + Server Hello)
-
客户端打招呼:你的浏览器向网银服务器发送一个“Client Hello”消息。里面包含了:
- 浏览器支持的TLS版本号。
- 支持的对称加密算法列表(如AES)。
- 生成的一个随机数(Client Random)。
-
服务器回应并出示凭证:服务器返回一个“Server Hello”消息,里面包含了:
- 选定的TLS版本和对称加密算法。
- 生成的一个随机数(Server Random)。
- 最关键的东西:服务器的 SSL证书。
这个SSL证书是什么?
它就像服务器的“数字身份证”,由全球公认的、受信任的第三方机构(证书颁发机构,CA,如DigiCert, Let‘s Encrypt)签发。证书里包含:
- 网站信息:域名(
www.mybank.com)。 - 公钥:服务器的公钥。
- 签发者:是哪个CA签发的。
- 数字签名:CA用自己的私钥对整个证书内容进行加密后得到的一个“签名”,用于防伪。
第2步:验证身份(证书验证)
你的浏览器收到证书后,会进行严格的“身份证”真伪查验:
- 检查签发机构:浏览器和操作系统中都预置了所有受信任CA的根证书(即CA的公钥)。浏览器会用对应CA的公钥去解密证书里的数字签名。如果能成功解密,并且解密出的摘要信息与证书内容计算出的摘要一致,就证明两件事:
- 证书是真的:这张身份证确实是由受信任的CA颁发的,不是伪造的。
- 证书未被篡改:内容完整无误。
- 检查域名:浏览器会检查证书上写的域名是否与你正在访问的域名(
www.mybank.com)一致。
如果任何一步验证失败,浏览器就会弹出著名的红色警告,告诉你连接不安全。验证通过,就意味着你确认了“和我通信的就是真正的mybank.com,不是中间人冒充的”。
第3步:安全地传递“密码本”(密钥交换)
身份确认后,就要解决核心问题:如何生成一个只有双方知道的、用于后续对称加密的“会话密钥”。
- 生成预主密钥:你的浏览器会再生成一个随机数,叫做“预主密钥”。
- 用公钥加密:浏览器用从服务器证书中提取的服务器公钥,加密这个“预主密钥”。
- 发送加密后的预主密钥:将这个加密后的预主密钥发送给服务器。
关键点来了:由于这个预主密钥是用服务器的公钥加密的,所以世界上只有持有对应私钥的真正的服务器才能解密它。即使黑客截获了这段数据,也因为没有私钥而无法解密。
现在,通信的双方(你的浏览器和服务器)都拥有了三个随机数:
- Client Random
- Server Random
- 预主密钥
双方会用同样的算法,根据这三个随机数,独立计算生成一个一模一样的“主密钥”。这个主密钥就是接下来用于对称加密的“会话密钥”。
你看,这里完美利用了非对称加密的安全性,来传递对称加密的密钥,解决了密钥分发问题!
第4步:开始安全通信(对称加密)
握手阶段结束!从现在开始,双方所有的HTTP数据(你的登录密码、转账请求、服务器返回的账户余额)都将使用刚刚生成的会话密钥进行对称加密(比如AES算法)后传输。
因为对称加密速度极快,所以能保证海量数据传输的效率。
总结与比喻
我们可以把整个HTTPS过程比喻成一次安全的线下交易:
- Client/Server Hello:你(浏览器)和商家(服务器)见面,互相打招呼。
- 证书验证:商家向你出示他的营业执照(SSL证书),你仔细检查营业执照是否由正规的工商局(CA) 颁发,并且执照上的公司名是否与商家招牌一致。这一步确认了商家的真实身份。
- 密钥交换:你随机想好一个复杂的临时密码(会话密钥),然后把它写下来,塞进一个商家提供的、只有他自己有钥匙的透明保险箱(用服务器公钥加密) 里,交给商家。商家用自己的私钥打开保险箱,看到密码。现在你们俩有了一个共同的秘密密码。
- 安全通信:接下来你们所有的交易对话和金钱往来,都用这个临时密码进行加密(比如用密码本写成暗语),确保即使被旁人听到也听不懂。因为对称加密效率高,所以可以流畅地进行大量沟通。
所以,HTTPS的实现是一个混合加密的典范:
- 非对称加密(RSA等) 用于安全地交换对称密钥和身份认证。
- 对称加密(AES等) 用于高效地加密实际的传输数据。
正是这套精妙的机制,守护着我们在互联网上的每一次安全访问。
问:为什么要用Client Random,Server Random,预主密钥生成一个会话密钥,而不是由客户端直接生成一个会话密钥,用公钥机密发送给服务器,Client Random,Server Random在发送时不是会被截获吗?
这是一个非常深刻且关键的问题!你完全抓住了HTTPS设计中的精妙之处。你的想法在理论上是可行的,但使用三个随机数来生成主密钥(会话密钥)是出于绝对的安全冗余和未来安全性的考虑。
下面我详细解释为什么这么做是更优的选择。
核心原因:防御“密钥妥协”和实现“前向保密”
你提出的方案是:
- 客户端生成一个“会话密钥”。
- 用服务器的公钥加密它。
- 发送给服务器。
这个方案的主要风险在于:如果服务器的私钥在未来某个时间点泄露了,会有什么后果?
答案是灾难性的:攻击者可以记录下你所有的加密通信流量,等某天窃取到服务器的私钥后,就可以解密历史上所有用该公钥加密过的“会话密钥”,从而解密全部的过往通信记录。
这种安全特性被称为前向保密 或完美前向保密。PFS是TLS协议追求的一个重要安全目标,它的意思是:即使服务器的长期私钥泄露,也不会导致过去会话的加密密钥被破解,从而保护历史通信的安全。
三随机数方案如何实现更强的安全性?
现在我们来分析“Client Random + Server Random + 预主密钥”的方案。
1. 为什么需要预主密钥?
预主密钥的作用和你设想中的“会话密钥”类似,它是生成最终主密钥的核心原料。它由客户端生成,并用非对称加密安全地传递给服务器,确保了只有合法的服务器能拿到它。
2. 为什么需要两个随机数(Client Random + Server Random)?
这两个随机数是公开的、明文传输的。你担心它们被截获是对的,但这正是设计的巧妙之处。它们的作用不是保密,而是参与“搅拌”。
最终的主密钥不是预主密钥本身,而是由三个随机数通过一个复杂的伪随机函数共同生成的。
可以把它想象成一个非常复杂的“配方”:
主密钥 = PRF(预主密钥, "master secret", Client Random + Server Random)
- PRF:是一个伪随机函数,可以理解为一个单向的、不可逆的“搅拌机”。
- 预主密钥:是核心秘密原料。
- 两个随机数:是公开的“调味料”,确保每次生成的“菜”都独一无二。
即使攻击者截获了Client Random和Server Random,他也毫无用处,因为他缺少最关键的“预主密钥”这个秘密原料。
对比两种方案的安全性
| 特性 | 你的方案(直接传会话密钥) | 三随机数方案(标准TLS) |
|---|---|---|
| 流程 | 会话密钥 = 客户端生成 | 主密钥 = PRF(预主密钥, Client Random, Server Random) |
| 前向保密 | 不具备。服务器私钥泄露 => 所有历史会话密钥泄露 => 所有历史通信被解密。 | 可以实现PFS。关键在于预主密钥的生成和交换方式。 |
| 密钥的随机性来源 | 仅依赖于客户端随机数生成器的质量。 | 依赖于客户端、服务器双方的随机数生成器,随机性质量更高,更不易预测。 |
关键升华:如何真正实现“前向保密”?
你可能会问,即使用了三个随机数,如果预主密钥还是用服务器的RSA公钥加密的,那和你的方案有什么区别?不还是怕服务器私钥泄露吗?
你问到点子上了! 标准的RSA密钥交换确实不提供前向保密。为了解决这个问题,现代TLS有一个更优的密钥交换方式:Diffie-Hellman密钥交换。
在基于DH的密钥交换中:
- 客户端和服务器各自独立生成一个临时的DH私钥和对应的公钥。
- 他们通过Hello消息交换各自的DH公钥(这部分是明文的)。
- 客户端用自己的临时私钥和服务器的临时公钥,计算出一个“共享秘密”。
- 服务器用自己的临时私钥和客户端的临时公钥,也能独立计算出同一个“共享秘密”。
- 这个“共享秘密”就作为预主密钥!
这样做的革命性好处是:
- 预主密钥从未在网络上传输过,它是双方各自计算出来的。
- 用于计算预主密钥的临时私钥在本次会话结束后就被立即销毁。
- 即使攻击者记录了全部通信,并且在未来某天窃取了服务器的长期RSA私钥,他也无法计算出当时的预主密钥,因为那需要已经销毁的临时DH私钥。
在这种情况下,主密钥 = PRF(共享秘密, Client Random, Server Random)。由于共享秘密的计算依赖于一次性的临时密钥,而Client Random和Server Random只是公开的“盐”,共同确保了本次会话密钥的唯一性和短暂性。
结论
所以,回答你的问题:
- 为什么不用一个? 用一个简单的会话密钥,无法实现前向保密,安全性较低。
- 为什么用三个?
- 预主密钥:提供最核心的机密性,并通过DH算法等实现前向保密。
- Client/Server Random:作为公开的“盐”,增加了主密钥的随机性和唯一性,确保即使预主密钥偶然重复,最终的主密钥也完全不同。同时,它们使得握手过程具有“活性”,防止重放攻击。
简单来说,Client Random和Server Random不怕被截获,它们的存在就是为了和秘密的预主密钥进行混合,生成一个仅限本次会话使用的、独一无二的、且与会话双方都相关的强大密钥。这是一种深度防御策略,是密码学严谨性的体现。
问:我还是不太理解 上面你假设通信流量被保留 并且私钥泄露的情况 直接传递会话密钥不行,但是同样的情况 第二种就没事了吗?
您这个问题问到了最核心、最精妙的地方!我完全理解您的困惑,之前的解释可能跳过了关键区别。让我们彻底把这个问题讲透。
您的感觉是对的:如果一直使用RSA方式加密预主密钥,那么即使加了两个随机数,也依然无法避免服务器私钥泄露导致历史通信被解密的问题。
两个随机数的加入,主要提升了随机性,但没有解决前向保密问题。
真正的分水岭,在于“预主密钥”是如何生成的,以及它是如何实现“交换”的。 这里有两条完全不同的技术路径:
路径一:RSA密钥交换(无前向保密)
这就是我们最初讨论的方式,也是您产生疑问的场景。
- 流程:
- 客户端生成
预主密钥。 - 客户端用服务器的RSA公钥加密
预主密钥,发送给服务器。 - 双方用
预主密钥+Client Random+Server Random生成主密钥。
- 客户端生成
- 安全分析:
- 攻击者确实可以录制下整个TLS握手过程的数据包,包括那个用RSA公钥加密后的
预主密钥。 - 如果一年后,服务器不小心泄露了它的RSA私钥。
- 那么攻击者就可以用这个私钥,去解密一年前录制好的那个加密数据包,从而得到
预主密钥。 - 一旦得到
预主密钥,再结合同样被录制下来的、明文的Client Random和Server Random,攻击者就能完整地计算出当年的主密钥,从而解密所有历史通信。
- 攻击者确实可以录制下整个TLS握手过程的数据包,包括那个用RSA公钥加密后的
结论:在这个路径下,您是对的。加入两个随机数并不能防御“录制-日后私钥泄露-解密”这种攻击。这种方案确实不具备前向保密性。
路径二:Diffie-Hellman密钥交换(实现前向保密)
这是现代TLS(如ECDHE算法)采用的、能真正实现前向保密的方式。它的逻辑完全不同,请您仔细看区别:
- 流程:
- 客户端和服务器各自独立生成一套一次性的、临时的DH密钥对(包含一个临时私钥和一个临时公钥)。
- 在Hello消息中,双方交换各自的临时公钥(这部分是明文的,可以被录制)。
- 最关键的一步:客户端用自己的临时私钥和服务器的临时公钥,通过一个神奇的数学公式(离散对数),计算出一个共同的
预主密钥。 - 同样,服务器用自己的临时私钥和客户端的临时公钥,也能独立计算出完全相同的
预主密钥。 - 这个
预主密钥从未在网络上传输过!它是在双方本地计算出来的。 - 双方再用这个
预主密钥+ 两个随机数生成主密钥。会话结束后,立即销毁双方的临时私钥。
- 安全分析(针对您假设的场景):
- 攻击者录制下整个握手过程,包括双方交换的临时公钥。
- 一年后,服务器的长期RSA私钥泄露了。
- 此时,攻击者能做什么?他试图计算当年的
预主密钥。 - 但计算
预主密钥需要什么?需要一方的临时私钥! - 而这个临时私钥在当年那次会话结束后就已经被服务器销毁了,攻击者即使拿到现在的长期RSA私钥,也永远无法获得那个一次性的临时私钥。
- 由于缺少这个关键原料,攻击者无法计算出
预主密钥,因此也无法解密历史通信。
这就是前向保密的魔法所在!
直观的比喻
让我们用比喻来强化理解:
- RSA方式(无PFS):就像您把
预主密钥写在一张纸上,放进一个需要特定钥匙才能打开的保险箱(服务器公钥加密),然后把保险箱寄给对方。攻击者可以把保险箱整个拍下来(录制)。如果日后他偷到了那把钥匙(服务器私钥),他就能打开当年拍下的保险箱照片里的锁,拿到纸条。 - DH方式(有PFS):像是一个神奇的“颜色混合”协议。
- 您和服务器各自私下选择一种秘密颜色(临时私钥)。
- 然后公开交换一种由秘密颜色和公共颜色混合出的新颜色(临时公钥)。
- 您拿到对方的公开混合色后,再混入自己的秘密颜色,得到最终颜色(
预主密钥)。 - 对方也做同样操作,得到相同的最终颜色。
- 核心:旁观者(攻击者)只看到了公开交换的混合色,但他永远无法从中反推出你们各自的秘密颜色,因此也无法知道最终的秘密颜色是什么。会话一结束,你们就把自己的秘密颜色忘掉(销毁)。日后即使你其他的长期秘密泄露,也和这次“颜色混合”无关。
总结
所以,您的问题的最终答案是:
您最初的直觉是正确的。如果TLS只使用简单的RSA加密来传递密钥,即使加入两个随机数,也无法防御“录制-日后解密”攻击。
因此,现代安全的HTTPS连接会优先使用基于Diffie-Hellman的密钥交换算法(在TLS中通常被称为DHE或ECDHE)。正是这套机制,而不是单纯的两个随机数,提供了至关重要的“前向保密”特性,使得即使服务器长期私钥泄露,历史会话依然安全。
两个随机数的作用更多是增加随机性、防止重放攻击,并与当次会话绑定。而实现前向保密的重任,是由密钥交换算法本身(如ECDHE)来承担的。希望这次解释彻底解决了您的疑惑!

浙公网安备 33010602011771号