端到端加密入门 · 讲义与学习笔记
搞懂微信与 WhatsApp 如何做到「只有你们能看」消息
整理:问学·科技
第 1 关 · 对称加密——一把钥匙锁箱子的直觉
用大白话讲清对称加密的原理、密钥长度为何决定安全,以及「钥匙怎么送出去」的死穴。
「锁与钥匙」的核心比喻
想象一个最简单的场景:小明想给小红写一封悄悄话,不能让路上的快递员偷看。
他拿来一只带锁的小铁箱——只有配的那把钥匙既能锁上、也能打开。他把悄悄话纸条放进去,「咔嗒」一声用钥匙把箱子锁上,然后把这只上锁的箱子交给快递员。
**这一步就叫「加密」**——把原来能直接读懂的内容(明文),用某种方式打乱,让中间人就算拿到也看不懂。
那只上锁的箱子在邮路上传啊传,快递员拎着它走街过巷——他看得到箱子,但打不开,看不到里面写了什么。**这只「上锁的箱子」就叫「密文」**——它就是原文经过加密之后的样子,外表完整、内容外人看不见。
箱子到了小红手里。小红拿出小明事先给她的那把钥匙(可以是当面给、可以是提前约好藏在哪里),「咔嗒」把锁打开,取出纸条读。**这一步就叫「解密」**——把密文还原成原本能读懂的内容。
**而那把「同一把钥匙」,就叫「密钥」**。注意两个关键词:「同一把」——加密用一次、解密还用这一把;「钥匙」——它就是能解开这段对话的全部秘密。
把这一整段流程画出来,就是这样:
flowchart LR
A[小明<br/>想说的话] --> B[放进铁箱]
B --> C[用钥匙锁上<br/>这就是加密]
C --> D[上锁的铁箱<br/>在邮路上传递<br/>这就是密文]
D --> E[小红 收到箱子]
E --> F[用同一把钥匙打开<br/>这就是解密]
F --> G[小红 读到原话]
回头看,流程里其实只出现了**四样东西 + 一个对称关系**:
- **明文**:小明本来想说的话,能直接读懂
- **加密**:用钥匙把明文锁进箱子的动作
- **密文**:上锁的箱子——外表完整、内里外人不可见
- **密钥**:那把既能锁、也能开的钥匙
- **解密**:用同一把钥匙把箱子打开、还原出明文的动作
加密和解密是**完全相反**的两个动作——一个把信息从「能看懂」变成「看不懂」,一个把信息从「看不懂」变回「能看懂」。但它们用的是**同一把钥匙**。这就是「对称」两个字最朴素的来源:加密、解密是镜像的两步,而那把钥匙站在正中间,**一头对着上锁,一头对着开锁**。
把三个词摆在一起记:加密是动作,密文是动作之后的产物,解密是反向动作。密钥贯穿始终——加密时要用它,解密时还要用它。
最后记住一个最重要的直觉:**密文本身不神秘,它只是一只「外人打不开的箱子」**。加密这件事真正难的地方,从来不是「怎么锁」——锁本身谁都会做,难的是「钥匙怎么交到对方手里而不被别人抄一份」。这个死穴,我们后面专门拆。
**要点:**对称加密就是「同一把钥匙既能锁、也能开」——加密是把明文上锁变成密文,解密是用同一把钥匙把密文打开还原成明文。
加密与解密的反向操作
上一节用一只上锁的铁箱定义了四个词:明文、加密、密文、密钥。这一节专门抠一个词——为什么这套玩法叫「对称」加密?对称两个字不是随便取的,它就藏在那把钥匙上。
「对称」在日常里是什么意思
先把「对称」从密码学里拿出来,看它在生活里长什么样:
- 一张人脸,左半边和右半边对照着长——对称。
- 一对翅膀,从身体中间往两边展开——对称。
- 算术:3 + 5 = 8,8 - 5 = 3。加法和减法是**一对相反的操作**,但它们针对的是**同一个数 5**。
这几件事的共同点是:**有两件相对的事,长得就像照镜子,但站在中间那个轴/数只有一个**。锚点的两边是镜像的,这就是「对称」在日常里的直觉。
把这个直觉套回加密
把「镜像 + 同一个锚点」套到加密场景上——
- 左边的动作:**加密**——把明文锁进密文里。
- 右边的动作:**解密**——把密文打开还原成明文。
- 站在正中间的那个锚点:**同一把钥匙**。
加密要用它,解密还要用它;加密的方向是「锁」,解密的方向是「开」——两个动作方向相反,但**共用一把钥匙**。这就是「对称」两个字真正的含义:不是「两边东西一样大」那种对称,而是「左右两个动作都围着同一把钥匙转」。
画出来就是这张图:
flowchart LR
A[明文<br/>能读] -- 加密<br/>用同一把钥匙锁上 --> B[密文<br/>读不懂]
B -- 解密<br/>用同一把钥匙打开 --> C[明文<br/>能读]
K[🔑 同一把钥匙] -.加密用.- A
K -.解密用.- B
注意图里**「同一把钥匙」这四个字出现了两次**——一次挂在加密那条箭头上,一次挂在解密那条箭头上。这不是啰嗦,这正是「对称」的全部秘密:**左边的动作和右边的动作共用一把钥匙**。
反过来想:如果不是同一把呢?
为了把「对称」吃透,我们反着推一下:假如加密用 A 钥匙、解密用 B 钥匙,A 和 B 是两把不同的——这种加密就不叫「对称加密」,叫**「非对称加密」**。我们后面会专门拆它,本节先记一个判断口诀:
> 加密和解密用的是不是同一把钥匙?是 → 对称;不是 → 非对称。
「对称 / 非对称」这两个词,不是按「哪个更安全」「哪个更新」分的,而是按「**钥匙是不是同一把**」分的。
算术类比再加固一下
你肯定熟加法。加法有个反操作叫减法:3 + 5 - 5 = 3,两个动作方向相反,但**都用到了同一个数 5**。加密和解密的关系和加法、减法是**同一类**——
- 加法 = 「把 5 锁进 3 里」,得到 8。
- 减法 = 「用 5 把 8 打开」,回到 3。
- 5 既是「锁」的关键,也是「开」的关键——**它就是那把「钥匙」**。
加法、减法围着同一个数 5 转;加密、解密围着同一把钥匙转。这就是密码学家为什么管它叫「对称」。
**要点:**「对称加密」里的「对称」,指的就是**加密和解密这俩相反动作,围着同一把钥匙转**。锁上要用它、打开还要用它——只此一把、各用一次、方向相反,这就是「对称」两个字的全部含义。
密钥长度与暴力破解
上一节我们搞懂了对称加密的核心:加密和解密共用同一把钥匙。这一节要回答一个很自然的问题——**那黑客能不能把这把钥匙一把一把试出来呢**?
还真能试。专业术语叫「暴力破解」(brute force):不靠聪明,只靠蛮力——把可能的钥匙从 0000… 一路试到 9999…,总有一把能对上。这种攻击简单粗暴,但威力如何,全看一件事:**总共得试多少把**。
从日常密码锁看「钥匙数」
先用你熟悉的场景来感受这件事。
你家门口那种数字密码锁,每位是 0-9:
- 1 位密码(0-9):10 种可能,半秒就能试完。
- 2 位密码(00-99):100 种可能,认真点一分钟搞定。
- 4 位密码:10 000 种——手机 PIN 码就是这个量级,黑客软件几秒钟能跑完。
- 6 位密码:1 000 000 种——银行卡密码 6 位,专业设备也跑得动。
规律一眼能看出来:**密码每加一位,可能的组合数就乘以 10**。这就是所谓的「指数级增长」——它的恐怖之处在于,位数只多几位,要试的时间就不再是「多一点点」,而是「多到天荒地老」。
真实加密锁:每多 1 位,乘以 2
进入电子世界,「一位」不再是 0-9 十个数字,而是一个「比特」(bit)——只有 0 或 1 两种可能。所以电子锁的规律更夸张:
- 1 bit:2 种可能
- 4 bit:16 种
- 8 bit:256 种
- 16 bit:65 536 种
- 32 bit:约 43 亿种
- 64 bit:约 1844 亿亿种
- **128 bit:约 3.4 × 10³⁸ 种**
- 256 bit:约 1.16 × 10⁷⁷ 种
注意:**每多 1 bit,可能的钥匙数就翻一倍**。所以 128 位的加密锁,要试的钥匙数大致是 34 后面跟 37 个零那么多个——这个数字大到人脑根本装不下。
给你一个数量级锚点
光说「3.4 × 10³⁸」你可能没感觉。换成你熟悉的东西:
- 地球上所有沙粒:约 7.5 × 10¹⁸ 颗。
- 可见宇宙中的星星:约 10²⁴ 颗。
- **128 位加密的可能钥匙数:3.4 × 10³⁸ 个**。
- 比地球上所有沙粒加起来**多出约 200 亿亿倍**。
- 比可见宇宙中所有星星加起来**多出约 10¹⁴ 倍**(一百万亿倍)。
换句话说,让一个黑客站在地球上「暴力试钥匙」,**他这辈子要试的钥匙数,比地球上每一粒沙子、每一片星空加起来还多**。
那把全球计算机都调起来呢?
更狠一点——假设不是一个人,而是「全球一起上」:
- 全球最强的超级计算机每秒大约能试 10¹⁵(一千万亿)次。
- 即便保持这个速度,要把 3.4 × 10³⁸ 把钥匙全部试完,需要:
- 3.4 × 10³⁸ ÷ 10¹⁵ ≈ 3.4 × 10²³ 秒
- ≈ 10¹⁶ 年
而宇宙的年龄才 138 亿年(约 1.38 × 10¹⁰ 年)。**试完全部钥匙花的时间,是宇宙年龄的约一百万倍**——宇宙烧光了,钥匙还没试到一半。
也许你会想:那「全宇宙的原子」呢?可见宇宙大约有 10⁸⁰ 个原子,确实比 10³⁸ 大不少——但这不改变结论:就算把每个原子都变成一台计算机同时帮我们试,**穷举时间也仍然远远超过宇宙寿命**。决定这件事的不是「钥匙数比原子多还是少」,而是「**跑完穷举要花多少个宇宙寿命**」。
**这就是为什么 AES-128(128 位对称加密)被全球金融、军事、政府广泛采用**——不是因为它「相对安全」,而是它在物理意义上几乎不可能被暴力破解。从 128 位再加到 256 位,不是为了再加几倍安全(128 位已经基本破不了了),而是为了让数学家们在心理上更踏实、留更多余地。
把这一节和上一节合起来
对称加密的安全感,来自两个事实叠在一起:
flowchart TD
A[对称加密为什么安全] --> B[加密、解密用同一把钥匙<br/>小偷必须猜中这把钥匙]
A --> C[钥匙位数足够长<br/>比如 128 位]
B --> D[小偷只能暴力试]
C --> E[可能钥匙数等于 2 的 128 次方<br/>约 3.4 乘 10 的 38 次方]
D --> F[试完全部钥匙]
E --> F
F --> G[需要约 10 的 16 次方年]
G --> H[比宇宙年龄 10 的 10 次方年<br/>还长约 100 万倍]
H --> I[物理上不可能]
暴力破解是「理论上唯一通用」的破解方法——不管算法多复杂,密钥对不上就是打不开。**但 128 位把这条最后的路也堵死了**。
**要点:**对称加密的安全,本质是「**钥匙的可能数量大到暴力试不完**」;每多 1 位,可能的钥匙数就**翻倍**——128 位就已经是「试到宇宙毁灭也试不完」的数量级,所以全世界才放心用。
对称加密的死穴:钥匙怎么送
前面三节我们把对称加密讲透了:加密和解密用同一把钥匙,钥匙足够长(128 位)就几乎不可能被暴力破解。听起来挺完美,对吧?
可惜——**这套完美方案里,藏着一个能让它彻底废掉的死穴**。这一节就来拆掉它。
故事:Alice 和 Bob 决定用上锁的箱子通信
接上一节的场景:Alice 想给 Bob 发一条只有他能看的信息。俩人商量好:
- 买一把**只有他俩有钥匙的特殊挂锁**(这种锁配两把一样的钥匙)。
- 一人留一把,箱子从此只能由他俩打开。
问题来了:Alice 和 Bob 在两个城市,怎么把第二把钥匙送到 Bob 手里?
第一次尝试:寄快递
最自然的办法——Alice 把钥匙装进信封,交给快递员送到 Bob 家。
flowchart LR
A[Alice] -->|信封里装钥匙| K[快递员]
K -->|信可能已经被拆| B[Bob]
K -.->|偷看并抄下钥匙| H[黑客/小偷]
请你站在 Bob 的角度想:钥匙已经从 Alice 手里到过快递员手里了,**你怎么知道快递员没多配一把**?你怎么知道他没把信封拆开看一眼、然后原样封好?
答案是:**你不知道。** 任何中间经手的人——快递员、邮局扫描员、分拣员——都可能在「物理接触」的那一刻把钥匙抄下来。
第二次尝试:换个更安全的快递公司?
换顺丰?换联邦快递?换武装押运?
没用。**问题不在快递公司靠不靠谱,在「中间经手」这件事本身**。任何运输渠道——快递、挂号信、电报、互联网——都有一个共同点:
> 信息在从 A 到 B 的路上,**必然要经过一段 A 和 B 都不在场的中间地带**。而那一段,归别人管。
互联网也没好到哪去。你发出去的每一个数据包,要经过无数个路由器、交换机、海底光缆。任何一个节点被攻破,钥匙就泄露了。
第三次尝试:用加密来保护钥匙本身
那 Alice 想:我再拿**另一把钥匙**把「钥匙」加密一下不就行了?
但等一下——**这把新钥匙怎么送到 Bob 手里?** 老问题又回来了,只不过换了一把钥匙而已。
**再加密一层?** 那第三把钥匙怎么送?第四把呢?……不管套多少层,最后总有一把「最底层的钥匙」是必须物理递送的——而只要物理递送,就回到了快递员问题。
这就像两个人站在河两岸想握手,**但脚下没有桥**。你可以造一万架梯子,但只要最底下那一截没有桥墩撑住,整件事就塌了。
这个死穴的本质
把这件事抽象出来看,对称加密的死穴是:
> **加密者和解密者必须共享同一把钥匙;而任何「把同一把钥匙送给对方」的过程,本身又需要被加密保护。**
这是个**先有鸡还是先有蛋**的死结。纯靠对称加密,**逻辑上永远解不开**。
破局的曙光:换一种锁
要解开这个死结,思路必须跳出「用同一把钥匙」的框框。我们需要一种**完全不一样的锁**——
想象一下:这种锁有**两把不同的钥匙**:
- 一把是「锁上专用」,可以随便复制、随便发给任何人(包括快递员、黑客)——**谁拿到都能锁、但都打不开**。
- 另一把是「打开专用」,只有 Bob 有一把,**绝对不能离开 Bob 身边**。
那么流程就变成:
- Alice 找 Bob 要一把「锁上专用」的钥匙——这把**不怕被快递员看见**,因为他拿着也只能锁、不能开。
- Alice 用这把公开的「锁上钥匙」把箱子锁好寄给 Bob。
- Bob 收到后,用只有自己有的「打开钥匙」开锁。
**整个过程里,没有任何一个环节需要把「打开钥匙」寄出去过**。死结解开。
这种「两把不一样钥匙」的锁,就叫做**非对称加密**。它的两把钥匙,分别叫**公钥**(公开的、锁上用的)和**私钥**(私密的、打开用的)。
> 公钥随便发给任何人都不怕,私钥永远不出门——这就能解掉「送钥匙」的死结。
把这一关串起来
flowchart TD
A[对称加密:四步走完] --> B[1. 锁与钥匙的比喻<br/>一只上锁的箱子]
A --> C[2. 加密与解密<br/>同一把钥匙<br/>所以叫「对称」]
A --> D[3. 密钥长度<br/>128 位比宇宙原子还多<br/>暴力破解跑不完]
A --> E[4. 死穴:钥匙怎么送<br/>寄送过程会被偷听]
E --> F[破局思路<br/>换两把不一样钥匙的锁<br/>即非对称加密]
对称加密本身**几乎无懈可击**(暴力破解跑不完),但它要求双方「事先共享一把钥匙」——而「共享」这件事,在现实世界里做不到绝对安全。这是设计上的死结,不是技术上的小瑕疵。**要解开它,需要换一种「两把不一样钥匙」的新锁——也就是非对称加密**。
**要点:**对称加密的安全建立在一把共享钥匙上,但「把钥匙安全送到对方手里」这件事**逻辑上就解不开**——你总得有一把钥匙是要物理递送的;而这逼出了非对称加密——一种「公钥随便传、私钥绝不离手」的新型锁。

学习笔记
对称加密核心概念
一把钥匙锁箱子的比喻
Alice 给 Bob 写悄悄话:把纸条放进带锁铁箱,锁上后交快递员送出,Bob 收到后用同一把钥匙开锁。
对应五要素:
- **明文**:本来能直接读懂的内容
- **加密**:用钥匙把明文锁进箱子的动作
- **密文**:上锁的箱子,外表完整、内里外人不可见
- **密钥**:既能锁也能开的那把钥匙
- **解密**:用同一把钥匙把箱子打开、还原出明文的动作
三者关系:加密是动作,密文是动作之后的产物,解密是反向动作;密钥贯穿加密与解密两步。
最关键的直觉:密文本身不神秘,只是「外人打不开的箱子」。加密真正难的不是「怎么锁」,而是「钥匙怎么交到对方手里而不被别人抄一份」。
「对称」二字的来源
日常里的对称
- 人脸左右对照、翅膀两边展开——中间一个轴,两边镜像。
- 加法与减法方向相反,但都围着同一个数(如 3+5-5=3 都用到了 5)。
套回加密
- 左边动作:加密(把明文锁进密文)
- 右边动作:解密(把密文打开还原成明文)
- 正中间锚点:**同一把钥匙**
两个动作方向相反,但共用一把钥匙——这就是「对称」的全部含义。
加密和解密用的是不是同一把钥匙
> 加密和解密用的是不是同一把钥匙?是 → 对称;不是 → 非对称。
「对称/非对称」不是按「哪个更安全」「哪个更新」分,而是按「钥匙是不是同一把」分。
暴力破解:钥匙数指数级增长
数字锁:每加一位 ×10
- 1 位:10 种
- 2 位:100 种
- 4 位:10 000 种
- 6 位:1 000 000 种
电子锁:每多 1 bit ×2
- 8 bit:256
- 32 bit:约 43 亿
- 64 bit:约 1844 亿亿
- **128 bit:约 3.4 × 10³⁸ 种**
- 256 bit:约 1.16 × 10⁷⁷ 种
128 bit 的数量级感受
- 地球上所有沙粒:约 7.5 × 10¹⁸ 颗
- 可见宇宙中的星星:约 10²⁴ 颗
- 128 bit 钥匙数:3.4 × 10³⁸ 个
- 比沙粒多出约 200 亿亿倍
- 比星星多出约 10¹⁴ 倍(一百万亿倍)
全球超算也跑不完
- 全球最强的超级计算机每秒约 10¹⁵ 次
- 试完全部 128 bit 钥匙需 3.4 × 10²³ 秒 ≈ 10¹⁶ 年
- 宇宙年龄约 1.38 × 10¹⁰ 年
- **所需时间是宇宙年龄的约一百万倍**
AES-128 被全球金融
AES-128 被全球金融、军事、政府广泛采用,不是因为「相对安全」,而是它在物理意义上几乎不可能被暴力破解。从 128 位再加到 256 位,不是为了再加几倍安全,而是为了让数学家们在心理上更踏实、留更多余地。
对称加密的死穴:钥匙怎么送
第一次:寄快递
**第一次:寄快递** Alice 把钥匙装进信封交给快递员——中间经手的人(快递员、扫描员、分拣员)都可能抄下钥匙,Bob 无法知道。
**第二次:换更安全的快递公司** 没用。问题不在快递公司靠不靠谱,而在「中间经手」这件事本身——任何运输渠道都有 A 和 B 都不在场的中间地带,归别人管。互联网也一样(路由器、交换机、海底光缆)。
**第三次:用加密保护钥匙本身** 拿另一把钥匙把「钥匙」加密一下?这把新钥匙怎么送到 Bob 手里?老问题又回来了。再加密一层?第三把、第四把怎么送?……不管套多少层,最后总有一把「最底层的钥匙」必须物理递送——只要物理递送,就回到快递员问题。
加密者和解密者必须共享同一把钥匙
> 加密者和解密者必须共享同一把钥匙;而任何「把同一把钥匙送给对方」的过程,本身又需要被加密保护。
这是「先有鸡还是先有蛋」的死结。**纯靠对称加密,逻辑上永远解不开。**
破局方向
跳出「用同一把钥匙」的框框,用两把不同的钥匙:
- 「锁上专用」钥匙:可以随便复制、随便发给任何人,拿到只能锁不能开
- 「打开专用」钥匙:只有 Bob 有一把,绝对不能离开 Bob 身边
这样整个过程里没有任何环节需要把「打开钥匙」寄出去——死结解开。
这种「两把不一样钥匙」的锁叫做**非对称加密**,两把钥匙分别叫**公钥**(公开的、锁上用)和**私钥**。
第 2 关 · 非对称加密与公钥私钥
能讲清公钥与私钥各自的角色,以及「公钥公开也安全」的不可逆直觉原理。
「信箱」比喻:公钥锁、私钥开
上一关我们学到对称加密——一把钥匙既能锁也能开。但这就引出一个棘手的问题:钥匙怎么从 Alice 传到 Bob 才不被快递员抄一份?这一关我们换个思路:能不能让 Alice 和 Bob 用「不一样的钥匙」?办法是——把锁和钥匙**拆成两件不同的东西**。
一把能扔给别人的锁——信箱的比喻
想象街边一个很特别的信箱,它长这样:
- **上面有一个投信口**,口子足够大,任何路人都能塞一封信进去。
- **信箱本身带锁**,盖子合上后只有专用钥匙能从里面打开。
- 邮递员能看到的只有投信口——他能把东西塞进去,但没法把信从里面掏出来。
这个带投信口的信箱就是**「公钥」**——它是你愿意展示给全世界的东西。任何人能拿到它、能用它的投信口往里投东西。
而**那把开箱子的钥匙**就是**「私钥」**——它只有你一个人有,从不示人。
谁拿什么?
这一对东西是**配套的**,由同一个人(我们叫他 Bob)一起生成:
- **Bob 留下私钥**(开箱子的钥匙),藏在口袋里,谁也不给。
- **Bob 把公钥(带投信口的信箱)复印 N 份**,发给所有想给他写信的人——Alice、Carol、David、还有路上的快递员。公钥这东西你扔到大街上都行,因为它的设计就是:拿到它的人,**只能往里塞,没法从里面取**。
请特别注意:私钥**永远**只在主人手里;公钥**满天飞**。这是这一对东西的默认姿态。
怎么用它发「悄悄话」
粗略感受一下流程(细节下一节再展开):
- Alice 找 Bob 要一把公钥(一只带投信口的信箱)。
- Alice 把写好的信从投信口塞进去,**盖子扣上,锁死**。
- Alice 把锁好的信箱寄回给 Bob。中间经手的人再多、再想偷看——没有钥匙,打不开。
- **只有 Bob 用自己的私钥开锁**,把信取出来读。
整个过程从头到尾,**没有发生过「秘密传递钥匙」**这件事。钥匙(私钥)从来没离开过 Bob 的口袋——这正是非对称加密解决上一关「钥匙怎么传」问题的核心思路。
最关键的方向感
请把这一节的中心思想刻进脑子里:
- **公钥 = 投信口(入)**。外人能做的只是「往里投」。它是一个**只进不出**的入口。
- **私钥 = 开箱的手(出)**。只有主人能从里面打开、把东西取出来。
- 两者方向**相反**,但必须是一对才能配合——配错对就打不开。
一句话总结这一节的全部内容:**公钥是公开的「投信口」,私钥是主人独享的「开箱钥匙」;东西往里投是公开的,从里面取出来只有主人做得到**。这就是非对称加密「方向感」的全部——下一节我们再具体聊聊,这个「投信 + 上锁」的动作是怎么让消息变得「外人打不开」的。
**要点:**公钥 = 公开的投信口(外人只能往里投、锁上),私钥 = 主人私藏的开箱钥匙(只有它能从里面打开);方向是「公进、私出」。

加密方向:公钥锁、私钥开
上节回顾:公钥是个带投信口的信箱
上一节我们建立了一个核心意象:公钥是「任何人都能往里投、但没法从里面取」的投信口;私钥是主人独享的「从里面开箱」的工具。
但有个问题还没展开:Alice 把信塞进信箱以后,怎么保证**半路上没人偷看**?这一节我们就盯紧这一步,把「加密」这个动作讲透。
投进去,就是「上锁」的动作
把上一节的流程再走一遍,但这次请把注意力集中在那个**盖子扣上的瞬间**。
想象 Alice 写了封绝密信:「项目预算 50 万」。她要做的不是直接寄给 Bob,而是:
- 找 Bob 要来他的公钥——就是那只带投信口的信箱。
- 把信折好,从投信口**塞进去**。
- 关键动作:**把信箱的盖子扣上,锁死**。
「塞信 + 扣盖」这两步合起来,就是**用公钥加密**的完整动作。听起来平平无奇,但它做到了一件神奇的事:
- 信进了箱子,箱子**盖子已经合上、锁死**。
- 这时候任何人——快递员、邮局的扫描员、路过的好奇路人——拿到这只锁好的箱子,**都打不开**。
- 哪怕他手上有一只**一模一样**的「投信口型信箱」(也就是 Bob 公钥的复制品),也**撬不开**。
公钥只能锁,根本没有「开」的能力
为什么复制一只一模一样的信箱也开不了?这就要回到上一节定下的方向感:
**公钥这把「工具」的设计只让外人做一件事——「投信」。** 投信口是只进不出的,盖子一旦合上,公钥自己也撬不开——它结构上就不具备「开箱」那个能力。
这正是非对称加密「非对称」三个字的核心:上锁和开锁是**两件不同的事**,由两件不同的工具完成,并且「上锁」这件工具你爱发多少份都行,「开锁」那件打死只能有一份。
路上经手再多人都无所谓
锁好之后,Alice 把这只**封死的**箱子通过任何普通方式寄给 Bob——普通快递、普通邮件、过几道中转站,路上经手多少人她都不在乎。
箱子到了 Bob 手里,他从口袋掏出**唯一的私钥**,插进锁孔,「咔嗒」一声打开。信取出来,原文「项目预算 50 万」读到了。
这里有一个特别值得记住的细节:**「开箱」这个能力从设计上就只属于私钥**。整条路上经过的所有人——Alice 自己没私钥、邮递员没私钥、中转站的服务器没私钥——他们就算截到了箱子,**物理上根本没法打开**。
flowchart LR
A[Alice 写明文<br/>项目预算 50 万] --> B[用 Bob 的公钥<br/>塞进去 + 扣盖锁死]
B --> C[密文箱子<br/>路上随便传]
C --> D{谁能打开}
D -->|邮递员| E1[打不开]
D -->|中转服务器| E2[打不开]
D -->|Alice 自己| E3[也打不开]
D -->|只有 Bob 用私钥| F[还原明文<br/>项目预算 50 万]
为什么「公钥公开」反而安全
很多人听到这里会本能地紧张:公钥满天飞,那别人拿到公钥不就能解密了吗?
答案就在方向上:**公钥的「能力」被限定在「合盖、上锁」这一个动作上**。它就像一把只能顺时针拧 90 度的钥匙——你能用它锁,但你想让它再逆时针转回来开门,**结构上根本不支持**。
所以「公钥公开」这件事一点都不危险——你公开的只是一个「只能上锁、不能开锁」的工具。公钥越公开,大家给你写信反而越方便;私钥则打死不能公开,一公开整个系统就崩了。
**要点:加密方向就是「公钥锁、私钥开」——发件人用对方的公钥把消息锁进箱子,路上任何人都打不开;只有对方口袋里的私钥能开。公钥公开不危险,是因为它根本不具备「开」的能力。**
签名方向:私钥锁、公钥验
上节回顾:公钥锁,只有私钥能开
上一节我们学到了「加密」方向:发件人用对方的公钥把消息锁进箱子,路上谁都打不开,只有对方的私钥能开。整套动作解决的是**保密**问题——不让中间人偷看内容。
但还有一种完全不同的麻烦:Bob 收到消息后,**他怎么知道这条消息真的来自 Alice**?万一是个骗子冒名顶替呢?这一节我们就来解决这个**身份**问题。
签名问题:怎么证明「这真的是我发的」
在真实世界里,我们怎么证明一封信是某人亲笔写的?靠的是**签名**——笔迹、印章、骑缝章。这些东西有个共同特点:
- 签名/印章是**那个人独有的**,别人仿造不出来(理论上)
- 收到信的人只要看到签名,就能确认「对,是他写的」
- 而且签名是**绑在信纸上的**——你把信纸上的字改了,签名就对不上了
数字世界里能不能也搞一套「数字签名」?能,思路还更巧妙——**直接把上一节的私钥反着用**。
反着用:私钥「锁」,公钥「验」
请回忆上一节的工具:
- 公钥:能「锁」但不能「开」的东西
- 私钥:能「开」对应公钥所「锁」的东西
现在换个思路:用 Alice **自己的私钥**去做「锁」这个动作,会发生什么?
会发生一件很神奇的事:任何拿到 Alice **公钥**的人,都能**把这个锁打开**。
「等等,」你可能立刻反应,「私钥不是只有 Alice 自己有吗?公钥不是谁都能拿到吗?那岂不是所有人都能解开?这不就没意义了?」
意义在于**这个动作的目的完全不同**:
| | 加密 | 签名 | |---|---|---| | 用谁的私钥/公钥? | 对方的公钥 | 自己的私钥 | | 谁打得开? | 只有对方(用对方私钥) | 任何人(用我公钥) | | 解决什么问题? | 保密:别人读不到 | 验真:证明是我发的 |
**加密**是「我要藏起来,不让你看」;**签名**是「我大大方方给你看,但你要能确认是我本人」。
印章类比:独一无二的私章 + 公开发行的印鉴册
让我用一个更具体的画面来帮你记住这个反过来的方向。
把 Alice 的私钥想象成**她的私章**——物理上独一无二,全世界只有她手里有那一枚。
把 Alice 的公钥想象成**公安局公开发行的「印鉴对照册」**——里面登载了 Alice 私章的形状、纹路、凹凸特征,任何人都可以去查。
现在 Alice 写了一封公开信(不是加密,就是普通能读的信),她要证明「这真的是我写的」:
- Alice 拿出自己的私章,在信的末尾**盖一个章**
- 她把信 + 章一起寄出去
- 收到信的 Bob,去翻那本公开的「印鉴对照册」,找到 Alice 的登记信息
- Bob 把信上的章和对照册上 Alice 的章一对比——**完全吻合**
- Bob 得出结论:「这封信确实是 Alice 亲手盖的章」
为什么这个推理成立?因为**只有 Alice 手里有那枚私章**。别人哪怕偷看了对照册,知道章长什么样,也**造不出第二枚一模一样的私章**——私章的细节(哪些凹凸、哪些纹路)远不是看一眼就能复刻的。
签名有两个重要特性
第一:**签名绑死在消息内容上**。如果中间有人偷偷把「我同意」改成了「我拒绝」,章就对不上了——验证就会失败。这就是签名的「防篡改」能力:签了就不能偷偷改。
第二:**签名不藏内容**。所有人都能读到消息原文,签名的目的只是**证明作者身份**,不是保密。
所以一条带签名的消息长这样:
原文:「同意,签字画押」 ← 谁都能读 签名:[Alice 的私章印记] ← 任何人都能验
用上节的工具反一反
把上一节和这一节合起来看,你会发现公钥和私钥这对工具真的很妙——**同一对工具,反着用了两遍**:
flowchart TD
A[同一对公钥 + 私钥] --> B[正向:加密]
A --> C[反向:签名]
B --> B1[用对方公钥锁<br/>只有对方私钥能开<br/>解决保密]
C --> C1[用自己私钥锁<br/>任何公钥都能验<br/>解决验真]
- 加密方向:公钥锁、私钥开 → 解决「不让别人读」
- 签名方向:私钥锁、公钥验 → 解决「证明是我发的」
**要点:签名是「私钥锁、公钥验」——用自己私钥给消息盖个「章」,任何拿到你公钥的人都能验证这个章是不是你盖的。关键在于:公钥人人都有,但只有你手里那一把私钥能盖出有效的章——这就是「验真」的原理。签名解决的是「这消息是不是真的来自某人」,不解决「藏起来不让别人读」。**

为什么不能反推——不可逆的日常直觉
上节的疑问:「公钥公开真的没事?」
上一节我们看到,Alice 把自己的公钥明晃晃地交给 Bob、甚至贴在网上让所有人都来塞信,她的私钥也一直没泄露。这件事之所以成立,**完全建立在一种特殊的能力上**——有些操作「正着做一步到位,反着做几乎不可能」。
这一节我们就来把这件事讲透。先说日常直觉,再说一点点数学(不讲公式)。
两个生活里的小实验
请你想象两件你肯定做过的事:
**实验一:烧纸**
- 拿一张纸,用打火机一烧——三秒,纸变成灰烬
- 让你把灰烬再变回那张纸?——不可能。不管你用什么办法,纤维结构、墨迹、字迹全毁了
**实验二:摔玻璃杯**
- 把玻璃杯从桌上推下去——啪,一下,碎成几十片
- 让你把碎片拼回原来那个完整的杯子?——理论上也许能把碎片对齐粘起来,但每条裂缝的形状、应力、位置已经永远丢失了,拼出来的也不是原来那个杯子
这两件事的共同点是:
- **正向操作极其简单**:烧一下、推一下,一秒完成
- **反向操作几乎不可能**:让纸从灰烬里长回来、让碎片自动拼回去——做不到
日常生活里这种「单向」过程到处都是:鸡蛋打碎容易、碎蛋壳复原难;冰块化成水容易、把水再变回「原来那块」冰很难(结出来是新的冰);一段磁带录完可以听,但要把听过的内容再缩回磁带上?不可能。
**为什么反向做不到?**因为过程中「信息」被永久破坏了。纸烧成灰,原来的字迹、纤维排列——这些细节根本没传到灰里;碎玻璃每条裂缝的位置一旦形成就再也不能找回。
这个直觉直接对应到公钥私钥
把上面的「单向操作」翻译到公钥私钥的语言:
- **私钥 → 公钥** 这一步,是「正向」——简单、一步完成
- **公钥 → 私钥** 这一步,就是「反向」——几乎不可能
所以公钥**公开完全没关系**——你把公钥告诉全世界,他们也只能完成「正向」那一半,根本反推不出你的私钥。
flowchart LR
A[私钥<br/>两个大数] -->|正向 相乘<br/>眨眼完成| B[公钥<br/>乘积]
B -.->|反向 分解<br/>比宇宙年龄还久| A
style A fill:#ffe4b5
style B fill:#90ee90
再贴近数学一点点(不讲公式)
数学家做这种「单向」操作,最经典的一招是:**大数乘法 vs 大数分解**。
具体说:
- 拿**两个 300 位的大整数**相乘
- 计算机算:眨个眼,几十毫秒出结果
- 现在只给你**乘积**(也就是 600 位的大数),让你**找回原来那两个 300 位的数**
- 全球最快的计算机一起算,**比宇宙的年龄还长**
你不需要懂为什么数学上难,只需要记住这个对比:
- **正向(两个大数相乘)**:瞬间
- **反向(把乘积分解回去)**:比宇宙年龄还久
类比到钥匙上:
- 两个 300 位的大数 = Alice 的私钥(两个秘密因子)
- 它们的乘积 = Alice 的公钥(公开给所有人的那个大数)
- 任何人都能拿公钥去「锁消息」——就像拿乘积去做正向运算
- 但**没人能把这个公钥拆成原来的两个因子**——也就没人能仿造出 Alice 的私钥
为什么这件事要特地讲一遍
很多科普书讲公钥私钥,会直接跳过这一节——「数学上很难就完了」。但**难在哪、为什么难**这层直觉不建立起来,你听到「公钥公开也安全」就会一直心里打鼓:万一哪天数学家想出新办法呢?万一量子计算机呢?
直觉是:这种「单向」不是某一种算法的偶然特点,而是**整个数学体系里普遍存在的硬骨头**。烧纸、摔玻璃这种日常生活里到处都是的「单向」过程,给了我们一个看得见摸得着的类比——原来「正着易、反着难」这件事在物理世界里早就是常识,只是被数学家用一种极端的形式搬到了数字世界。
**要点:公钥能公开、私钥不能泄露,根本原因是「不可逆」——正向操作(比如两个大数相乘)一步完成,反向操作(把乘积拆回去)即使动用全球算力也要算到宇宙尽头。这和「纸烧成灰、玻璃摔碎」是同一种日常直觉:信息一旦被破坏就回不去。**
对称与非对称的优劣对照
一个绕不开的问题
前面四节,我们学了两套完全不同的「锁消息」的办法:
- **对称加密**(第 1 节):你和对方**共用同一把钥匙**——这把钥匙既用来锁,也用来开
- **非对称加密**(第 2-4 节):你和对方**各有两把钥匙**——一把公钥(公开)、一把私钥(自留),方向反着用
一个绕不开的问题自然就冒出来了:**这两套办法,到底哪个更好?**
这一节给你一个诚实的答案:**两个都好,但各自的「好」是反过来的**——就像一辆超跑和一辆慢但能装很多东西的卡车,你不会二选一,你会看场景。
一张大白话对照表
| 维度 | 对称加密 | 非对称加密 | |---|---|---| | 速度 | 飞快,加密几个 GB 也就眨眼 | 慢得多,通常是前者的 1/100 到 1/1000 | | 钥匙传递 | 头疼——必须**事先**把同一把钥匙安全送到对方手里 | 不头疼——公钥随便传,私钥从不出门 | | 100 人互相聊天要管几把钥匙 | 4950 把(要疯)| 每人 1 公钥 + 1 私钥,共 200 把 | | 适合干的事 | 加密大块数据(聊天、视频、文件) | 加密小块数据(钥匙、短消息、签名) | | 生活类比 | 两边各有一把一模一样的家门钥匙 | 一个公开投递口 + 一个私藏钥匙圈 |
下面把表里最容易困惑的两点展开说说。
「速度差」到底有多大
这不是细微差别,是**百倍到千倍**的差距。
你电脑里最常见的对称算法叫 **AES**——现代笔记本加密一整个 GB 的视频只要零点几秒。**RSA**(最常见的非对称算法)做同样的活,同一台笔记本可能要好几十秒;要只签个名、加解密一段短文本那没问题,但拿它加密一整部高清电影,**用户会等到手机没电**。
所以你脑子里的画面应该是:
- **对称加密** = 一辆超跑:性能拉满,但前提是**双方得事先拿到同一把钥匙**才能启动
- **非对称加密** = 一辆慢卡车:不快,但有个牛本事——**不挑乘客、不需要事先安排**
「100 人要管 4950 把钥匙」是怎么回事
N 个人两两通信、每对人单独用一把对称钥匙,**需要的总数是 N(N-1)/2**:
- 10 个人:45 把
- 100 个人:4950 把
- 1000 个人:499500 把
而且这只是静态数字。每加一个新同事,你得给现有 N 个人**每人配一把新钥匙**并**安全送过去**。万一某把钥匙途中被人偷看一眼——**所有用过这把钥匙的对话都得作废重来**。
非对称方案下:每人就管自己的两把,新人加入只需要把自己的公钥发到群里,**完全不需要碰别人的私钥**。这才是非对称真正牛的地方——**不是「加密本身更快」,而是「管钥匙的代价小一个数量级」**。
flowchart TD
A[真实系统到底用哪个?] --> B{要加密什么?}
B -->|一次性交换钥匙<br/>或签名| C[用非对称<br/>慢但不用事先传钥]
B -->|聊天视频文件<br/>大量数据| D[用对称<br/>极快但需先有钥匙]
C --> E[用非对称<br/>安全传递一把对称密钥]
E --> D
D --> F[之后所有消息<br/>都用这把对称密钥加密]
style C fill:#90ee90
style D fill:#87ceeb
style E fill:#ffe4b5
style F fill:#87ceeb
一个具体例子
Alice 想给 Bob 发一段 1 GB 的视频:
- **纯用非对称**:Bob 那边可能要等几十秒甚至几分钟
- **纯用对称**:Alice 和 Bob 首先要安全共享同一把钥匙——**而这个「共享」本身就是大难题**(邮递员送过去?邮递员看一眼,钥匙就废了)
- **真实系统怎么办**:先**用 Bob 的公钥**(非对称)把一把**临时对称密钥**安全传给 Bob——这一步只加密 256 bit 的小数据,慢一点没关系;之后两人都**用这把临时对称密钥**(对称)加密那 1 GB 视频——快得飞起
这就是组合拳——**非对称解决「传钥」难题,对称解决「速度」难题**。
实际系统里什么样
真正端到端加密的协议(Signal、WhatsApp 用的那套)几乎都是这种组合——**用非对称来安全地「交换一把对称钥匙」,之后所有消息都用对称加密**。这种「先用非对称换钥匙、再用对称传消息」的套路,是端到端加密的**标准骨架**。
所以以后再听到「端到端加密」,脑子里浮现的不是某种神秘算法,而是这个画面:**先慢后快——用慢的解决传钥,用快的解决日常通信**。
**要点:对称加密**快得飞起**但有「必须事先安全传钥」的硬伤;非对称加密**慢得多**但天然解决传钥难题。两者不是谁取代谁——真实系统永远把它们**组合用**:先用非对称换一把对称钥匙,再全程用对称加密所有消息。**
学习笔记
公钥与私钥的方向感
- 公钥 = 公开的「投信口」,外人能往里投、锁上,但打不开——「公进不出」
- 私钥 = 主人独享的「开箱钥匙」,只此一份,从不出门——「私出不进」
- 一对工具由同一个人配套生成;公钥可复印 N 份满天飞,私钥永远只在主人手里
- 两者方向相反,但必须配对使用——配错对就打不开
加密方向:公钥锁、私钥开
- 发件人用**对方的公钥**把消息「塞进箱子 + 扣盖锁死」,整条链路上任何人都打不开
- 公钥的结构决定了它只能「合盖上锁」,不具备「开箱」能力——哪怕复制一份同款公钥也撬不开
- 只有持有对应私钥的收件人能从里面打开、读到原文
- 整条路上没有发生过「秘密传递钥匙」这件事——这是非对称加密解决对称加密「钥匙怎么传」问题的核心思路
- 「公钥公开」不危险:你公开的只是一个「只能上锁、不能开锁」的工具
签名方向:私钥锁、公钥验
- 发件人用**自己的私钥**给消息「盖章」,任何人用发件人的公钥都能验证这个章
- 解决的是**身份**问题(不是保密):证明「这消息确实是我发的」
- 类比:私钥是私章(独一无二),公钥是公安局公开的「印鉴对照册」(人人可查)
- 签名两个重要特性:
- **绑死在消息内容上**——内容被改,章就对不上(防篡改)
- **不藏内容**——原文谁都能读,签名只证明作者身份
| | 加密 | 签名 |
| | 加密 | 签名 | |---|---|---| | 用谁的私钥/公钥? | 对方的公钥 | 自己的私钥 | | 谁打得开/验得了? | 只有对方(用对方私钥) | 任何人(用我公钥) | | 解决的问题 | 保密:别人读不到 | 验真:证明是我发的 |
同一对工具反着用:公钥既能「锁」也能被用来「验」,私钥既能「开」也能被用来「锁」。
为什么不能从公钥反推私钥——单向操作
- 「正向极简单、反向几乎不可能」的过程在物理世界到处都有:烧纸、摔玻璃杯、鸡蛋打碎
- 对应到公钥私钥:**私钥 → 公钥**是「正向」一步完成;**公钥 → 私钥**是「反向」几乎不可能
- 数学上经典做法是「两个大整数相乘 vs 把乘积分解回去」:
- 两个 300 位大数相乘:眨眼完成
- 只给乘积,让你找回原来两个因子:比宇宙年龄还久
- 两个秘密因子 = 私钥;它们的乘积 = 公钥。公钥公开完全没关系,因为没人能把乘积拆回原因子
- 这种「单向」不是某一种算法的偶然特点,而是整个数学体系里普遍存在的硬骨头
对称 vs 非对称 优劣对照
| 维度 | 对称加密 | 非对称加密 | |---|---|---| | 速度 | 飞快(GB 级数据眨眼) | 慢得多,约为前者的 1/100 到 1/1000 | | 钥匙传递 | 头疼——必须事先安全送达同一把钥匙 | 不头疼——公钥随便传,私钥从不出门 | | 100 人互聊要管几把钥匙 | 4950 把 | 每人一公一私,共 200 把 | | 适合干的事 | 加密大块数据(聊天、视频、文件) | 加密小块数据(钥匙、短消息、签名) | | 生活类比 | 两边各有一把一模一样的家门钥匙 | 公开投递口 + 私藏钥匙圈 |
两套办法各有「好」的方向:对称快但钥匙传递麻烦,非对称慢但钥匙管理简单——看场景选用。
第 3 关 · 密钥交换——在不安全的信道上安全地递钥匙
能用「双方各出一半颜料」的思路讲清密钥交换原理,并能用「证书 / 信任锚」解释身份认证这一步为何能成立。
「染色混合」比喻:双方如何造出共同秘密
「染色混合」比喻:双方如何造出共同秘密
上回留下的悬念
上一节我们学到:对称加密快、便宜,但它有一道天堑——**钥匙怎么递**。非对称加密能解决递钥匙问题,但又慢又贵。
所以现实里的方案是**混合制**:用非对称加密**只递一把对称钥匙**,之后所有聊天内容都改用这把对称钥匙锁——又快又省。
但这里藏着一个魔鬼细节:「用非对称加密递对称钥匙」本身,也需要 Alice 和 Bob **在公开信道上交换公钥**。一条所有人都能听的信道上,怎么交换公钥才不会被中间人偷换?
这就是「密钥交换」要解决的事。最经典的一个方法叫 **Diffie-Hellman**,翻译成人话就是——**两端各出半份颜料,混出一个共同的秘密色**。
颜料实验:四步造出共享秘密
设想你(Alice)想和远方朋友(Bob)约好一个共同的秘密颜色,而你们之间的快递员被允许偷看任何一封信。
**第一步:约定一个公开的「起始颜料」**
你们事先说好一桶**金黄色**——这就是「公共黄」。这一步毫无秘密可言,写在协议里、贴在公告板上都行。
**第二步:各选一个秘密色,混出「半成品」发出去**
- Alice 偷偷在抽屉里拿出一瓶**红色颜料**(这就是她的秘密)
- Alice 把秘密红 + 公共黄倒在一起 → 调出**橙色**(半成品)→ 把橙色装瓶寄给 Bob
- Bob 偷偷在抽屉里拿出一瓶**蓝色颜料**(这就是他的秘密)
- Bob 把秘密蓝 + 公共黄倒在一起 → 调出**绿色**(半成品)→ 把绿色装瓶寄给 Alice
这时快递员**完全能看到**寄过去的橙色和绿色瓶子——他甚至可以抄下颜色带走。但他拿不到藏在 Alice、Bob 抽屉里的秘密红和秘密蓝。
**第三步:各自往「对方寄来的半成品」里混入自己的秘密色**
- Alice 收到 Bob 的绿色瓶子,往里**加入自己的秘密红** → 调出**深棕色**
- Bob 收到 Alice 的橙色瓶子,往里**加入自己的秘密蓝** → 也调出**深棕色**
**奇迹发生了:两人手里的最终颜色完全一样!**
flowchart LR
Y[公共黄<br/>人人可见] --> A[Alice 秘密红<br/>+ 公共黄 = 橙色]
Y --> B[Bob 秘密蓝<br/>+ 公共黄 = 绿色]
A -->|寄出橙色<br/>快递员可见| B1[Bob 收到橙色]
B -->|寄出绿色<br/>快递员可见| A1[Alice 收到绿色]
B1 --> F[Bob 绿色<br/>+ 秘密蓝 = 深棕]
A1 --> G[Alice 橙色<br/>+ 秘密红 = 深棕]
F --> H[双方共同秘密色<br/>深棕色]
G --> H
为什么两端能调出一样的颜色?因为数学上**混合顺序可以交换**——`(公共黄 + 秘密红) + 秘密蓝` 和 `公共黄 + (秘密红 + 秘密蓝)` 结果一致。两边只是走的路径不同,落到的是同一个颜色。
快递员为什么算不出来
快递员手上**只有**这些:
- 公共黄(公开的)
- 橙色(Alice 寄出的半成品)
- 绿色(Bob 寄出的半成品)
他没有的是:**秘密红、秘密蓝**。
关键在于——**颜料混合是单向的**。你能轻易把红+黄调成橙,但**看到橙色几乎不可能反推出「里头加了多少红、多少黄」**。哪怕你试遍所有红黄配比,要从橙色准确还原出原始红黄比例,在现实里要花几百年、几千年才能蒙对。这背后是数学上的「**离散对数难题**」——正向算极快,反向推极难。
所以快递员最后只能干瞪眼:他知道最终色应该是某种「深棕」,但他算不出具体是哪一个深棕,也就拿不到那把「对称钥匙」。
这把「共同秘密色」拿来干什么
调出共同的深棕色后,Alice 和 Bob 各自把这颜色**编码成一串数字**——这串数字就是他们的**共享对称密钥**。之后所有聊天内容都用这把对称钥匙上锁,速度快、代价低。
注意一件巧妙的事:**这把完整的钥匙,从来没有在信道上整体传递过**——它只是两端各凭自己那半份「秘密色」**算**出来的。这就是「**密钥交换**」这个名字的由来:双方**交换**了某些公开材料之后,**各自**在本地**换**出同一把钥匙。
顺手串回前两关
- 上一关学的「非对称加密」:本块里 Alice 和 Bob 互相寄「半成品颜料」时,**不一定要**用非对称加密保护——因为即使被偷看,第三方也算不出最终颜色。所以密钥交换这一招**比单纯非对称加密更省**。
- 上一关学的「对称加密」:本块算出的共享秘密色,最终就是用来当**那把对称钥匙**的——所以本块正好补上了「对称钥匙怎么从无到有造出来」这一环。
要点
「染色混合」用「公开色 + 各自秘密色 → 交换半成品 → 各加自己秘密色 = 共同秘密色」四步,让两端在不安全的信道上**算出了同一把对称钥匙**,而第三方即使看完全部通信,也因颜料混合不可逆而**算不出**这把钥匙。
中间人攻击:为什么「染色混合」还不够
上一节的方案,藏着一个大漏洞
上一节我们说:只要 Alice 和 Bob 各守好自己的秘密色,第三方就算看完全部通信也算不出最终色。这听起来挺完美对吧?
但我们漏算了一种人——**主动搞破坏的快递员**。
我们之前的假设是:快递员只能「看」,不能「动手脚」。可现实中一个怀有恶意的中间人,他不仅可以偷看,还可以**篡改**你和对方之间的每一封信。密码学里给他起名叫 **Mallory**(中间人 / Man-in-the-Middle)。
更可怕的是:Alice 和 Bob 两人**完全不会察觉**。
演一遍「偷换颜色」
回到上一节的实验,假设你和 Bob 约好用「染色混合」做密钥交换。Mallory 就蹲在你们俩中间——所有你寄给 Bob 的信、和所有 Bob 寄给你的信,他都能截下来改一改再转交。
**第一步:你照常动手**
你(Alice)选了秘密红,混出橙色半成品,寄出去。
**第二步:Mallory 在中间动手脚**
你寄给 Bob 的橙色,Mallory 收到了。但他**不转给 Bob**——他有自己的秘密绿。他把你寄来的橙色**藏起来**,换成他自己用「秘密绿 + 公共黄」调出来的**浅绿色**,寄给 Bob。
**第三步:Bob 也照常动手**
Bob 收到了那个「浅绿色」(其实来自 Mallory),以为是 Alice 寄来的,就用浅绿色 + 自己的秘密蓝,调出一个**深青色**——他以为这就是他和 Alice 共享的秘密色了。
**第四步:Bob 寄回来的颜色也被掉包**
Bob 寄出的「半成品」同样被 Mallory 截下,Mallory 再用自己另一套秘密色重新调一个,转给 Alice。
**最终结果**:
- Alice 手里那个「深色」,其实是和 **Mallory 共享**的。
- Bob 手里那个「深青色」,也是和 **Mallory 共享**的——而且和 Alice 那个不一样。
- Mallory 手里呢?**两边各一份,全有**。他可以解密 Alice 给 Bob 的每条消息(用和 Alice 的共享色),重新包装一下再用和 Bob 的共享色发给 Bob。中间想改什么改什么,Alice 和 Bob 完全不知道。
flowchart LR
A[Alice<br/>秘密红] -->|寄出橙色| M[Mallory 截下<br/>藏起 换成自己调的颜色]
M -->|伪装是 Alice 的颜色| B[Bob<br/>秘密蓝]
B -->|寄出半成品| M2[Mallory 再次截下<br/>换成自己调的颜色]
M2 -->|伪装是 Bob 的颜色| A2[Alice]
A -.->|以为和 Bob 共享| K1[共享色 Alice 与 Mallory]
B -.->|以为和 Alice 共享| K2[共享色 Bob 与 Mallory]
为什么这比「偷看」更危险
快递员只是偷看,你和 Bob 至少还能正常通信;中间人 Mallory 的招数更狠——
- **他让通信「看上去成功」**:你和 Bob 都没收到任何错误提示,反而能继续正常聊天。
- **他拿到的是完整的密钥**:他不是「猜」出来的,是实打实和你们**各算了一遍**。颜色对、算法对、协议也没报错。
- **你们不知道发生过任何事**:从你和 Bob 的视角看,这一切都像一次完美的密钥交换。
这就是「中间人攻击」可怕的地方——**它是无声无息的失败**。上一节的「染色混合」在数学上是对的,但**缺少一步关键的验证**:你和 Bob 怎么确信「那个寄过来的半成品,真的来自对方」?
顺着漏洞往下想
答案就在下一节里:要先**证明身份**——在你和 Bob 开始「染色混合」之前,先得确认你拿到的「对方公钥」真的属于 Bob 本人、而不是 Mallory 伪装的。
这一步叫做「**身份认证**」。它的核心武器就是我们上一关讲过的——**数字签名**。
要点
「染色混合」本身数学上没问题,但只要中间人 Mallory 能**主动拦截并替换**通信,他就能同时和两端各「染一次」,分别骗取两把共享色——双方还都以为自己在和对方通信,毫不知情。所以密钥交换之前,必须再加一步:**证明「你拿到的那个公钥,确实来自你声称的那个人」**。
身份认证:用数字签名证明「你就是你」
漏洞到底出在哪一步
上一节我们看到,Mallory 的招数是**偷换你和 Bob 之间的「公开色」**。你俩之所以被骗,是因为你们只验证了「颜色本身对不对」(数学是否正确),但**没有验证「这个颜色到底是谁寄来的」**。
所以在动手「染色混合」之前,必须先加一步——**确认对面真的就是 Bob**。密码学里这一步叫「**身份认证**」(Authentication)。
印章的比喻
想象 Bob 桌上有一枚独一无二的印章。任何文件被他盖过,你一眼就能认出「这是 Bob 的章」。
印章有三个特点:
- **只有 Bob 能盖**——别人没这枚章,仿不出来
- **任何人都能验**——章的图案是公开的,谁都可以拿去过目
- **盖章和文件是绑死的**——你没法把 Bob 盖在 A 文件上的章,抠下来贴到 B 文件上
数字签名的结构,正好一一对上:
- 私钥 = 那枚章(只有持有人能「盖」)
- 公钥 = 章的验证器(任何人都能用它验「这一处盖章是不是真的」)
- 签名 = 私钥对一段内容「盖」完之后的产物
- 验证 = 用公钥检查「这段内容确实被对应的私钥盖过」
套回染色混合的场景
具体到我们上一节的实验,Bob 在把自己的「公开色」寄给 Alice 之前,多做一步:
**Bob 这一端**:用私钥对「我 Bob,本次公开色是橙色」这段话签名 → 得到一个签名串 → 把「公开色 + 签名串」一起打包寄出去。
**Alice 这一端**:收到之后,先**不混合**,先**验签**:
- 用 Bob 的公钥去检查那个签名
- 验证通过 → 说明「这段公开色 + 自报身份」确实出自持有 Bob 私钥的人
- 确认后,才用这个公开色开始「染色混合」
flowchart TD
A[Bob 用私钥<br/>对公开色签名] --> B[公开色 + 签名<br/>一起寄出]
B --> C[Mallory 截下]
C --> C1{想用自己公开色替换?}
C1 -->|用自己私钥重签| C2[新签名<br/>自报是 Bob]
C1 -->|原样转发| D[Alice 收到]
D --> E[Alice 用 Bob 公钥<br/>验证签名]
E -->|通过| F[确认是 Bob 寄来的<br/>开始染色混合]
E -->|不通过| G[拒收 报警]
为什么 Mallory 这次就过不去了
关键在于**签名和内容是绑死的**:
- 签名是 Bob 用私钥对「**这段特定的公开色**」盖的章
- Mallory 截下之后想做坏事,他得同时做到两件事:
- 把公开色换成自己的——这一步他能做
- 再用**自己的私钥**重签一遍,伪装成「这是 Bob 签的」——但 Alice 会用 **Bob 的公钥**去验签
- Alice 一验就露馅:「**这个签名不是 Bob 那枚章盖的**」→ 拒收
- 如果 Mallory 不动公开色、原样转发 Bob 的真签名,那 Alice 验出来「这确实是 Bob 签的原内容」——**Bob 的公开色没被动过,Mallory 也搞不了破坏**
所以数字签名真正堵死的是:「**你没法冒充一个你拿不到私钥的人**」。这是上一节 Mallory 整套骗术的前提。
还剩一个小问题没解
等等——Alice 用来验签的「Bob 的公钥」又是从哪来的?
如果是 Bob 临时在信里告诉你「这是我的公钥」,**那 Mallory 一样能在最开始就把公钥一起偷换了**。所以这一步得建立在「**你早就通过某种可信渠道拿到了 Bob 的真公钥**」之上。
这个问题——「公钥本身也可能被掉包,怎么办」——是下一节要解决的事。
要点
在「染色混合」之前加一步**数字签名验证**:发送方用私钥对公开色签名,接收方用对方公钥验签——通过,就证明这条消息确实来自持有对应私钥的人。这一步堵死了 Mallory 冒充 Bob 的可能。
证书与信任锚的极简交代
鸡生蛋的问题
上一节我们用数字签名堵住了 Mallory——但留了一个小尾巴:**Alice 用来验签的「Bob 的公钥」到底是从哪来的?**
如果这个公钥是 Bob 第一次接触 Alice 时在网络上传过来的,那 Mallory 完全可以**在最开始**就把 Bob 的公钥掉包成自己的。这样一来,Alice 后续所有的「验签」其实都在验 Mallory 的签名——整个签名机制瞬间失灵。
这其实是个**鸡生蛋**的问题:
- 你要靠公钥验签 → 但你得先**确认这个公钥确实属于 Bob**
- 怎么确认?→ 得有一个**可信的人**替你背书
- 可信的人又怎么可信?→ 这条链子得有个**起点**
身份证的比喻
想象你第一次去银行办业务,柜员说「请出示身份证」。她根本不认识你,但**她信任身份证,因为身份证是公安局发的**。把这里的角色一一对应:
| 角色 | 对应到我们的问题 | |------|------------------| | 你(办业务的人) | 拿到 Bob 公钥的 Alice | | 你的身份证 | 一张写着「此公钥属于 Bob」的**证书** | | 公安局 | **CA(证书颁发机构)** | | 公安局的印章 | CA 用自家私钥对证书盖的「章」 | | 柜员手里那份「印章样本」 | 设备出厂时**预装**的 CA 公钥 |
证书本身不神秘——就是把「Bob 的公钥 + Bob 的身份信息」打包成一张电子单。**真正起作用的,是这张单上盖了 CA 的章。**
验证过程
flowchart TD
A[Bob 拿自己的公钥<br/>去 CA 申请证书] --> B[CA 核实 Bob 身份<br/>比如核验域名所有权]
B --> C[CA 用自家私钥<br/>对证书签名盖章]
C --> D[证书 随 Bob 公钥 一起寄出]
D --> E[Alice 收到]
E --> F[用 预装的 CA 公钥<br/>验证证书上的章]
F -->|通过| G[信任 这就是 Bob 的公钥]
F -->|不通过| H[拒收 报警]
G --> I[进入上一节流程<br/>用 Bob 公钥验消息签名]
注意这一下子**跳出了鸡生蛋**:CA 的公钥**不是网络上传来的**,是 Alice 用的设备(手机、浏览器、App)在出厂时**硬编码**进去的——你不必从 Bob 那里拿,也就不会被 Mallory 在信道上偷换。
这件事天天在你身边发生
**每次你看到浏览器地址栏那把小锁**——你点开「证书」看到的「颁发给 / 颁发者」——背后就是这一整套机制:
- 网站的公钥被打包成证书
- CA 在上面盖了章
- 浏览器用预装的 CA 公钥验签
- 通过,才让你连上
你从来没主动「信任」过任何一个网站,但**你还是敢在陌生网站上输信用卡号**——靠的就是「**没人一开始就真认识对方,但所有人都信任同一个印章**」的设计。
那对聊天 App 呢
端到端加密的 App(Signal、WhatsApp)需要的不是「服务器可信」,而是「**你和你朋友这两个终端之间的公钥确实是真的**」。这就有了两种路线:
- **借用证书体系**:让 CA 帮 App / 用户的公钥背书(很多场景这么做)
- **信任码 / 安全码**:让两人**当面**互相核对一串数字(Signal 里的「安全号码」就是这个作用)
具体怎么落地,不同 App 选法不同,但底层逻辑都一样:**必须有一个共同信任的起点**,否则谁也没法证明对面真的是谁。
要点
**证书 = 公开身份 + 公开公钥 + CA 签名章**;CA 是大家预先信任的印章机构,它的公钥内置在设备里、不从网络上传来——这一下子切断了「公钥本身被掉包」这条攻击链。这就是浏览器小锁和所有 E2EE 应用「信任一个陌生公钥」的底层逻辑。
前向保密:钥匙暴露也不影响历史消息
一个让人失眠的问题
先抛一个让你夜不能寐的场景:假设你今天用加密聊天的所有内容,对方都老老实实用你们的「长期密钥」(就是上一节那个被证书背书过的、跟着你账号走一辈子的私钥)在加密。**十年后的某一天,你的手机丢了,私钥泄露了。**
攻击者拿着这把你藏了十年的钥匙,能干什么?
- 解密**今天**以后的所有消息 → 这很正常,钥匙被偷了嘛
- 但更恐怖的是:他翻出**十年前**所有你收发的加密消息,一条一条**全部解开**
因为十年来你**一直在用同一把钥匙**——钥匙一旦丢,**整个历史**都被翻开。这就是普通加密协议的痛点。
换锁的比喻
把这事想成一把物理钥匙就明白了:
**没有前向保密的房子**:
- 业主十年来**就用一把钥匙**
- 小偷某天复印了钥匙 → 进出这房子**所有时候**的所有门,都畅通无阻
**有前向保密的房子**:
- 每天早上物业会**换一次锁芯**,把旧锁芯**当场销毁**
- 今天的钥匙只能开今天的门
- 明天一早,旧锁芯已经变成碎铁了,**谁也回不去**
- 即使小偷今天偷到了钥匙,也**只能开今天这一天的门**——明天的门、后天的门、去年某天的门,都开不了
这就是「**前向保密 (Forward Secrecy)**」的核心承诺:**今天泄露的钥匙,撬不动昨天、去年的门**。
它是怎么做到的——一次性钥匙
你可能会问:「天天换锁芯,钥匙从哪来?还得专门派人送?」
巧就巧在,这个送钥匙的机制,**正好就是上一节讲过的密钥交换**——而密钥交换每次都能**临时**算出一个新共享秘密。我们只要遵守一个原则:
> **每一条消息(或每一段会话)都用一次性的临时密钥加密,用完即弃。**
具体来说(简化版,便于理解):
- 双方各有**一个长期身份密钥**(证书背书过、十年不变那个)
- 每次**新开一个会话**或**发一条新消息**时,双方**临时再走一次密钥交换**(就像「染色混合」),算出一个**仅此一次**的共享秘密
- 这条消息用这个临时秘密加密
- **加密完就把这个临时秘密扔掉**——服务器、本地都不存
- 下一条消息,再来一次
像不像一扇「**用一次就换锁芯、用完锁芯就烧掉**」的门?每一条消息都有它**专属的一次性锁**,而这个锁用完就**永远消失**了——攻击者就算偷了今天的临时钥匙,也只能解今天这一条。
为什么需要这个特性
听起来是不是有点「过度设计」?我们来看两个真实威胁:
flowchart LR
A[长期密钥泄露<br/>手机丢了] --> B{有没有前向保密?}
B -->|没有| C[十年前到今天<br/>所有消息全部裸奔]
B -->|有| D[只能解密<br/>泄露那一刻之后的消息]
D --> E[历史消息安全<br/>因为临时密钥已销毁]
style C fill:#fdd
style D fill:#dfd
style E fill:#dfd
**场景一:服务器被拖库**。如果即时通讯服务商的服务器今天被入侵、被偷走所有历史消息数据库——在**有前向保密**的设计下,这些历史消息虽然存在服务器上,但**加密它们的临时密钥早就没了**(用一次就烧),数据库只是一堆**没人能解开的密文**。Signal、WhatsApp 敢公开说「我们看不到你的消息」「就算我们想看也看不到」,**靠的就是这一条**。
**场景二:未来解密攻击**。今天有人把你所有的加密消息**全部录下来**存着(NSA 这种机构就有这种能力),赌的是「也许十年后算力/算法能破解」。有前向保密的话,他们即使将来某天**真的攻破了你的长期密钥**,也**解不出**过去的密文——因为过去那些密文用的是**早已销毁的临时密钥**。这就是「前向保密」名字里「**前向**」的来历:**保护的是「往回看」的历史。**
Signal 的「双棘轮」:每条消息都换锁
行业标杆 Signal 协议把这事做到了极致——**每一条消息都换一次临时密钥**,技术上叫「**双棘轮算法 (Double Ratchet)**」。你可以理解成:
- 不仅**每次会话**换锁
- 连**一条会话里的每条消息**都换锁
- 而且新锁和旧锁之间有一条**单向的链**(只能从旧的推出新的,不能从新的反推旧的)——所以**回溯也回不去**
WhatsApp 用的就是这个协议(Signal 开源给它的),所以你用 WhatsApp 时的「端到端加密」**默认就带前向保密**。Telegram 的「秘密聊天」模式也有,但**普通云聊天模式没有**——这是两者安全性的一个关键差别。
要点
**前向保密 = 一次一密、用完即焚**:每条消息(或每段会话)都用临时生成的密钥加密、用完立刻销毁;这样即使长期密钥某天被偷,**历史消息也解不开**。这就是 Signal、WhatsApp 敢承诺「我们自己也看不到你消息」的关键设计。
学习笔记
密钥交换:从染色混合到信任链
对称加密快但需要双方共享同一把钥匙
对称加密快但需要双方共享同一把钥匙,现实方案是**混合制**:用非对称加密只递一把对称钥匙,之后通信改用对称加密。
但「递钥匙」本身也有漏洞:公钥在公开信道上交换,如何保证不被中间人偷换?
二、Diffie-Hellman:染色混合造共享秘密
四步流程
- **约定公共颜料**:双方约定一个公开颜色(如「公共黄」),写在协议里即可
- **各选秘密色、混出半成品寄出**:
- Alice:秘密红 + 公共黄 → 橙色,寄给 Bob
- Bob:秘密蓝 + 公共黄 → 绿色,寄给 Alice
- **混入对方半成品**:
- Alice:收到的绿色 + 自己的秘密红 → 深棕色
- Bob:收到的橙色 + 自己的秘密蓝 → 深棕色
- **结果一致**:双方最终颜色相同
**数学基础**:混合顺序可交换,`(公共黄 + 秘密红) + 秘密蓝` 与 `公共黄 + (秘密红 + 秘密蓝)` 结果一致。
为什么窃听者算不出来
窃听者只看到公共黄、橙色、绿色,**没有秘密红和秘密蓝**。颜料混合是**单向的**——正向极快,反向推极难(对应数学上的离散对数难题)。
三、中间人攻击:染色混合的致命漏洞
攻击方式
主动搞破坏的中间人(Mallory)不仅能看还能改:截下 Alice 的橙色换成自己调出的浅绿色转给 Bob;Bob 的半成品也被同样掉包。
**结果**:Alice 的共享色其实和 Mallory 共享,Bob 的共享色也和 Mallory 共享,Mallory 两边各一份,能解密一切。
为什么可怕
- 通信「看上去成功」,无错误提示
- Mallory 是**实算**出来的密钥,不是猜的
- 双方完全不知情
**根本原因**:只验证了「颜色对不对」(数学正确),**没有验证「这个颜色是谁寄来的」**。
四、数字签名:堵住身份验证的缺口
印章三特性
- 只有持有人能盖(私钥)
- 任何人都能验(公钥)
- 盖章和内容绑死(无法把 A 的章抠下来盖到 B 上)
Bob 寄出公开色之前
Bob 寄出公开色之前,先用私钥对「我 Bob,本次公开色是 X」签名,连同公开色一起寄出。Alice 收到后**先验签再混合**:用 Bob 的公钥验,通过才继续,不通过则拒收。
为什么堵得住 Mallory
签名和内容绑死。Mallory 想偷换公开色就得用自己的私钥重签,但 Alice 用的是 **Bob 的公钥**验签,一验就露馅。
五、证书与信任锚:公钥本身的信任问题
Alice 验签用的「Bob 的公钥」从哪来
Alice 验签用的「Bob 的公钥」从哪来?如果从网络上传,Mallory 也能在最开始就偷换成自己的公钥。
身份证比喻的角色对应
| 现实 | 密码学概念 | |------|-----------| | 身份证 | 写着「此公钥属于 Bob」的证书 | | 公安局 | CA(证书颁发机构) | | 公安局的印章 | CA 用私钥对证书的签名 | | 柜员手里的印章样本 | 设备出厂时**预装**的 CA 公钥 |
流程
- Bob 拿公钥去 CA 申请证书
- CA 核实身份(如域名所有权)后用私钥签名盖章
- Alice 收到证书,用**预装**的 CA 公钥验签
- 通过 → 信任这就是 Bob 的公钥,再进入上一节的验签流程
**关键突破**:CA 的公钥不是网络上传来的,是设备出厂时**硬编码**进去的,不会在信道上被偷换。
浏览器地址栏的小锁 = 同一套机制
浏览器地址栏的小锁 = 同一套机制:网站公钥打成证书、CA 盖章、浏览器用预装 CA 公钥验签。
六、前向保密:今天的钥匙暴露,翻不开昨天的消息
痛点
长期用同一把私钥 → 私钥一旦泄露 → **所有历史消息**都能被解开。
换锁比喻
- 没有前向保密的房子:一把钥匙用十年,被偷 = 进出所有时候
- 有前向保密的房子:每天早上**换一次锁芯,旧锁芯当场销毁**,今天的钥匙只能开今天的门,明早旧锁芯已成碎铁,谁也回不去
不长期复用同一把密钥
不长期复用同一把密钥,临时密钥即使将来泄露,历史会话也无法还原。
第 4 关 · 即时通讯中的端到端加密全流程
能完整讲清一条消息从打字发出到对方手机显示每一步如何发生,并能用大白话解释预密钥、X3DH、安全指纹这些后续会被反复引用的术语。
「第一次握手」:预密钥、X3DH 与安全指纹
你终于打开了一个新聊天窗口,输入「在吗?」,按下发送。对方在地球另一端,睡着呢——他手机都没开。你这条消息怎么就安全地「摆上」了他的床头?更关键的是,你怎么知道他醒来后看到的就是你发的那条、而不是被中间人偷偷换过的?
这正是端到端加密(E2EE)第一次握手要解决的两件事:对方不在线时怎么安全起跑、起跑前怎么确认对方真的就是对方。
一、对方不在线:第一次握手的现实难题
前面学过的 Diffie-Hellman(染色混合)有个前提——双方都得在线才能互发「半成品」。你发橙色过去,他得立刻接住、发绿色回来,你俩才能合出同一把共享颜色。
可在 IM(即时通讯)里,这前提根本不成立:你发消息的时间,对方八成在睡觉、坐飞机、地铁没信号。他不在线,DH 的第二步就卡住了——没有对方的「半成品」,你怎么算共享秘密?
二、预密钥:提前把投信口挂到服务器上
解决方案听起来有点笨,但很有效:每一方在自己在线的时候,提前生成一批「一次性信箱」(学术名叫预密钥 / Prekey),把它们的「投信口」(公钥那一半)批量上传到服务器上;另一半钥匙(私钥)则留在自己手机里,从不外传。
打个比方:Bob 每天出门前,会到驿站(服务器)挂一长串「一次性密码挂锁」——每个挂锁都能锁,但只能开一次。他把挂锁公开挂着,把开锁钥匙揣兜里带走。Bob 睡着以后,Alice 来取一把挂锁,把自己的消息锁上、塞进 Bob 的信箱。
下次 Bob 醒来,他兜里还揣着那把对应的钥匙,能打开 Alice 锁上的那一份。其他任何人都打不开——因为他没给过别人钥匙。
几个关键细节:
- 每个预密钥只用一次,用完就扔——这避免了「一把锁被开过太多次」的风险
- 服务器只存「投信口」(公钥),真正的开锁钥匙从不上传
- 用户在线时会批量补货,所以驿站的挂锁永远源源不断
flowchart LR Bob[Bob 手机] -- 批量上传公钥 --> Server[服务器] Server -- 提供一个预密钥公钥 --> Alice[Alice] Alice -- 用公钥锁消息 + 寄出 --> Transit[服务器中转] Transit -- 送达 --> Bob Bob -- 用本地私钥开锁 --> Msg[读到明文]
三、X3DH:把染色混合做成可异步的版本
DH 必须双方都在场,X3DH(Extended Triple Diffie-Hellman,扩展型三次 DH)的巧妙之处在于:它把 DH 拆成「能用预密钥代为完成」的样子。
具体而言,X3DH 把以下几把钥匙搅在一起算(细节不展开,但你可以理解为「染了不止一种秘密色」):
- Bob 留在服务器上的预密钥公钥(一次性)
- Bob 的身份钥匙公钥(长期不变,等同 Bob 的「名片」)
- Alice 自己当场生成的一次性临时公钥
- 还有 Bob 周期性轮换的签名预密钥(用来证明这一串预密钥确实是 Bob 上传的,没被别人替换过)
三(或四)次 DH 计算揉成同一把共享秘密——这正是「Triple」的来源。关键是:Bob 醒来时,拿到 Alice 寄来的「临时公钥」+ 自己手里的私钥,能算出和 Alice 完全一样的结果。整个过程不需要 Bob 当时在场——预密钥替他「存好了一半该发的东西」。
> 一句话总结:X3DH = 用预密钥 + 身份钥匙 + 临时钥匙,多染几层颜色,得出第一把会话钥匙。
四、安全指纹:怎么确认这真的是 Bob
还记得上节讲的中间人攻击吗?——Mallet 偷偷把 Bob 的公钥换成自己的,于是他能偷看甚至篡改消息。
预密钥没解决这个问题。服务器上挂的「Bob 的公钥」真的就是 Bob 的吗?Mallet 一样可以冒充:它可以同时给 Alice 一个「假 Bob 的预密钥」、给真 Bob 一个「假 Alice 的预密钥」,神不知鬼不觉。
端到端加密 App 的应对是安全指纹 / Safety Number:在你和对方的聊天界面里,会显示一串 60 位左右的数字(有时也用二维码或 emoji 组合)——这串数字是你和对方两人公钥的「指纹」。
使用方法很朴素:当面或电话里,把这串数字念给对方听(或扫一下对方的二维码)。两边对得上,就说明:
- 你拿到的「Bob 公钥」真的是 Bob 的
- Bob 拿到的「Alice 公钥」真的是 Alice 的
这相当于「线下再确认一次」,绕开了所有中间人能动手脚的环节。
五、雪崩效应:指纹为什么不会「差一位就凑合」
指纹能做到这一点,靠的是哈希函数一个看似简单但非常关键的特性——雪崩效应(Avalanche Effect):
> 输入哪怕只改一位(一个比特),输出会面目全非——通常一半左右的位都会翻转,和原值看不出任何亲缘关系。
举个例子(虚构数字):
- Bob 真实公钥的指纹:12345 67890 12345 67890 ……
- Mallet 伪造的「几乎一样」的公钥(只差一位)指纹:90812 34567 90812 34567 ……
两个指纹毫无相似。你念给 Bob 一听,秒发现「这不对啊」。
所以雪崩效应 = 把「1 bit 的差别」放大成「整串数字看起来都换了」。没有它,指纹就形同虚设——Mallet 稍微改动一下公钥,指纹还能和原来凑个八九不离十,你根本看不出来。
要点
**预密钥**让「对方不在线」不再是 E2EE 的拦路虎;**X3DH**把多组 DH 揉成第一把会话钥匙,Bob 醒来后能算出和 Alice 完全一致的结果;**安全指纹**配合哈希的**雪崩效应**,让哪怕一个比特的偷换也无藏身之地。
「每次会话」:用临时对称密钥加密单条消息
上一节我们用预密钥 + X3DH 算出第一把「共享秘密」,但「共享」和「能用它加密消息」之间还差一步——我们得把那个抽象的「共同颜色」变成一把能真正用来上锁的钥匙。
为什么不能全程用「公钥私钥」?
直觉上,既然已经搞定了公钥私钥,为什么不每条消息都直接用 Bob 的公钥锁、发给 Bob?
答案藏在两个字里:**速度**。
公钥私钥(非对称)那套算法做一次加密运算特别费 CPU。可以把它想象成一种「重型保险箱」——非常安全、几乎打不开,但开一次箱要花好几秒。把一条 1KB 的小消息塞进去还凑合,可 WhatsApp 里一张照片就是几 MB、一段视频几百 MB——要加密到什么时候?聊天体验直接卡死。
而对称加密(两边用同一把钥匙)则轻便得多——快到几乎感觉不到延迟。代价是:怎么把这把「同一把钥匙」安全地送到对方手里,不被中间人偷看?
混合加密:重型保险箱里只装一把轻锁
于是工程师想了个聪明的办法,叫**混合加密(Hybrid Encryption)**——「重锁」只用来开个头,之后全程用「轻锁」:
- **第一步(重锁开门)**:用 Bob 的公钥加密一把**临时生成的随机对称钥匙**(叫「会话钥匙 / Session Key」)。这把会话钥匙只有几十个字节,正好装得进重型保险箱。
- **第二步(轻锁开路)**:用这把会话钥匙,对真正的消息内容(文字、照片、视频)做对称加密——快如闪电。
发送出去时,数据大致长这样:
┌────────────────────────────────┐ │ [用 Bob 公钥锁住的会话钥匙] │ ← 重型保险箱,里面装着轻锁的钥匙 │ [用会话钥匙锁住的真实消息] │ ← 大包裹,轻锁锁得飞快 └────────────────────────────────┘
Bob 收到后反向操作:先用自己的私钥开重型保险箱(拿到会话钥匙),再用会话钥匙开大包裹(看到原文)。整条链路对服务器完全不可见。
flowchart LR A[Alice 生成随机会话钥匙] --> B[用会话钥匙加密消息] A --> C[用 Bob 公钥加密会话钥匙] B --> D[密文 + 加密后的会话钥匙] C --> D D --> S[服务器只看到密文] S --> E[Bob 收到] E --> F[Bob 用私钥解开会话钥匙] F --> G[用会话钥匙解开消息]
「每次会话」为什么强调「临时」?
你可能想问:既然上节算出了共享秘密,为什么还要再生成一把新的会话钥匙,而不是直接拿共享秘密当会话钥匙?
两个原因:
- **共享秘密是「颜色」,会话钥匙是「能开锁的钥匙」**——前者是数学上对齐的数值,后者是要喂给加密算法的具体格式,两者之间需要一次「提纯」转换
- **临时性更安全**——哪怕某一把会话钥匙因为某种原因被泄露,也只影响那一段会话,不会牵连历史消息
至于到底多久换一次锁、怎么换,则涉及更精细的设计思路。**先记住这个原则:会话钥匙的生命周期越短、越随机,泄露风险就越小。**
服务端到底看见了什么?
把上面所有步骤过一遍,服务器的视角就非常清楚了:
- ✅ **看得见**:每一段密文(外观像一串随机字符)、消息长度、发送时间、谁发给谁——这些「信封」信息
- ❌ **看不见**:消息里的任何一个汉字、照片里的任何一张脸、视频里的任何一帧
更关键的是,**服务端看到的密文是「不断变化的」**——同样的「在吗?」你发 100 次,服务器收到的是 100 段完全不同的乱码。这不是装饰,而是加密算法 + 临时钥匙的必然结果。哪怕服务端想拿两段密文「比一比有没有重复」,也比不出任何东西。
要点
**用非对称加密「装」一把对称钥匙送过去,之后所有消息都用这把临时对称钥匙来加解密——这就是混合加密。服务端只能看见不断变化的密文,看不见明文。**
「双棘轮算法」白话版:每条消息换一把钥匙
上一节我们知道了「每段会话一把临时钥匙」的思路——这已经是很大进步了。但顶级的协议还不满足于此,**Signal 协议家族**(WhatsApp、Signal 都在用)又往前走了一步:每一条消息单独一把钥匙,用完就扔、永不复用。这套机制叫做「双棘轮算法(Double Ratchet)」。
为什么「一段会话一把钥匙」还不够?
设想这个场景:你用 WhatsApp 聊了三年,加起来发了 10 万条消息,全程用的是同一把会话钥匙。某天你换手机,旧手机被送修、被偷、或者被执法部门没收——**只要这一把钥匙被提取出来,三年的 10 万条密文全部瞬间变成明文**。
密钥长期复用的代价在业界已有共识,所以才有了后面这套「每条换一把」的机制。
棘轮(ratchet):只能往前转的扳手
先认名字。「棘轮」是一种特殊的扳手——见过那种只能往一个方向拧、拧不动了就停在那里的工具吗?这就是棘轮。它对应的英文 ratchet 也叫「单向齿轮」:**只能往前走,不能倒退**。
双棘轮算法借用了这个意象:每一把新钥匙,都是从上一把钥匙「往前演进」出来的,**但你拿到新钥匙反推不出旧钥匙**。就像知道明天的天气是由今天决定的,但知道明天的天气绝对推不出今天是什么天气。
每条消息换一把钥匙,到底怎么换?
数学上有个概念叫「单向函数」——正向算极快,反向算几乎不可能。双棘轮用的就是这种函数。具体说:
第 1 条消息的钥匙 = K1 第 2 条消息的钥匙 = K2 = 某种单向变换(K1) 第 3 条消息的钥匙 = K3 = 某种单向变换(K2) 第 4 条消息的钥匙 = K4 = 某种单向变换(K3) ...
每一把钥匙只用一次,用完就丢。**黑客就算偷到 K3,他也只能用 K3 去解第 3 条那一条消息——他解不出 K2,也解不出 K4。**
flowchart LR K1[K1 第 1 条] -->|单向变换| K2[K2 第 2 条] K2 -->|单向变换| K3[K3 第 3 条 被偷的就是这把] K3 -->|单向变换| K4[K4 第 4 条] K4 -->|单向变换| K5[K5 第 5 条] style K3 fill:#ffe4b5
图中加粗那一格就是「被偷的那把」——它只覆盖那一条消息,前后两格根本无解。
「双棘轮」为什么是「双」?
因为有**两层棘轮同时工作**,职责分工不同:
- **内层(对称棘轮)**:就是上面那种「每条消息换一把钥匙」,保证单条粒度的安全
- **外层(DH 棘轮)**:每完成一次「一来一回」对话(Alice 发一条 + Bob 回一条),双方就换一把**根钥匙**,用这把新根钥匙去生成后面所有消息钥匙的种子
外层的存在解决了一种更隐蔽的威胁:**「长期窃听者顺藤摸瓜」**——想象一个黑客持续盯着你们的通信,他一直在录音每一段密文,攒了几年。某天他偶然偷到了一把钥匙,想顺势算出你们将来所有消息的钥匙。DH 棘轮让这种「顺藤摸瓜」变得不可能,因为「将来用什么钥匙」不是由「过去用了什么钥匙」单独决定的——中间隔了一道新的根钥匙做种子,每次一来一回就刷新一次。
「前向保密」与「后向保密」
加密学界给这种特性起了两个名字:
- **前向保密(Forward Secrecy)**:今天的钥匙被偷,**过去的**消息依然安全
- **后向保密 / 未来保密(Post-Compromise Security)**:今天的钥匙被偷,**将来的**消息依然安全
内层棘轮给前向保密,外层棘轮给后向保密。两者合起来,才是真正的「双棘轮」。
一个直觉小例子
你和同事每天发 100 条工作消息:
- 没用双棘轮:1 把钥匙扛 100 条,偷到一把 = 100 条全解
- 用了双棘轮:100 条 = 100 把不同的钥匙,偷到 1 把 = 只解那 1 条,其余 99 条无解
**这就是为什么 Signal、WhatsApp 把双棘轮当作核心卖点**——它把「一把钥匙的价值」从「一段会话」压缩到了「一条消息」。
要点
**双棘轮 = 内层每条换钥匙(单向演进、不能回推)+ 外层每轮换根钥匙(断绝顺藤摸瓜);泄露任何一把钥匙,影响范围只有那一条消息,过去和将来都安全。**
群聊里怎么做端到端加密
一对一聊过瘾了,群聊怎么办?
上一节我们看完了双棘轮在 1 对 1 场景下怎么玩——但现实是,你大部分聊天时间其实泡在群里:工作群、家庭群、闺蜜群、同学群。这些群动辄 5 人、20 人、500 人。**一对一的那套「一把锁一把钥匙」在群聊里直接套用会出大问题。**
最笨的办法:一条消息,复制 N 份,分别加密
最直白的群聊端到端加密是这么想的:
- 你(Alice)要给一个 50 人的群发一条消息
- 你把这条消息**用 50 个群成员各自的公钥分别加密一次**,生成 50 份密文
- 50 份密文全部发到服务器,服务器转发给 50 个人
- 每个人用自己私钥解开自己那份
这办法**安全上完全没问题**——服务端全程看不到明文。但问题来了:一条消息,群里 50 个人,就变成 50 份密文。**流量、电量、服务器带宽全都吃不消**。
真正的招数:发送者密钥(Sender Key)
WhatsApp、Signal 这些主流 App 在群聊里用的不是上面这种笨办法,而是一招非常聪明的**「一次分发、长期复用」**——学名叫**发送者密钥(Sender Key)**。
思路是这样的:
**第一步:分发阶段。** 当 Alice 第一次在群里发消息时,她临时生成一把「发送者密钥」(一把对称密钥)。然后她**用群里每个成员的公钥,分别把这把发送者密钥包起来**——50 个成员就包 50 个「专属信封」。这 50 个信封跟着她的第一条消息一起发出去。
**第二步:复用阶段。** 群里的 50 个人收到后,各自打开自己的信封,取出同一把发送者密钥。从这一刻开始,Alice 之后再发任何消息,**只需要用这把发送者密钥加密一次**。一条密文,50 个人都能解(因为他们手里都有同一把钥匙的副本)。
flowchart TD A[Alice 生成发送者密钥] --> B[用 50 个成员各自的公钥<br/>分别包成 50 个专属信封] B --> C[50 个信封随首条消息发出] C --> D[每位成员拆开自己信封<br/>得到发送者密钥] D --> E[之后 Alice 每条消息<br/>只需用发送者密钥加密一次] E --> F[50 位成员各自用手中的<br/>发送者密钥解开同一条密文] style A fill:#fff4e1 style E fill:#e1f5ff
注意这张图的关键:**从第二步开始,Alice 那边只加密一次,所有人共享同一把对称钥匙**。流量、电量、算力全降下来。
现实类比:物业公告栏 + 50 把钥匙
你可以把发送者密钥想成是这么个场景:
- 你(Alice)要给小区 50 户业主发物业通知
- 你准备一个**带锁的公共公告栏**,锁的钥匙复制 50 份
- 你把 50 份钥匙**分别装进 50 个只有业主本人能开的专属信封**里,挨家挨户送过去
- 以后每次发通知,你**只往公告栏里贴一份**——50 户业主拿各自的钥匙都能打开看
- 公告栏只有一份,通知只贴一份,省事
「发送者密钥」就是这个公告栏的锁;50 个专属信封就是用 50 个人各自公钥包起来的密钥分发包。
群聊里的「换锁」也照样要搞
上一节我们说过,1 对 1 里为了前向保密,每条消息要换一次锁。**群聊里这套也得有**——Alice 的发送者密钥也要跟着「棘轮」往前走:每发一条消息,发送者密钥就用单向函数演化一次,群里所有 50 个成员也跟着同步演化。**这样即便黑客偷到了今天这把发送者密钥,他也只能解今天这一条——昨天和明天的消息,他都解不了。**
进群退群时也照样要换钥匙:新成员进群时,剩下的成员要重新分发一次新的发送者密钥(新成员拿不到旧密钥,自然看不到进群前的历史消息,这叫「新人看不到旧账」)。有人退群,剩下的成员换一把新锁,退群的人带不走新钥匙——**他以后再也看不见群里的新消息**,这叫「后向保密」。
三个术语,对照一眼
这一节蹦出来好几个名词,眼花缭乱。你只要记住这三个的对应关系就行:
- **发送者密钥**:Alice 自己的那把「群发专用锁」,一次生成、50 个人共用
- **成员链**:发送者密钥每发一条消息往前演进的轨迹,所有群成员要跟着同步走
- **群签名密钥**:群本身的「公章」,证明「这条消息确实来自本群成员」——但不告诉你是群里哪一位
至于这背后更深一层的数学机制(X3DH、MLS 协议里那些细节),你只要知道「每个成员都拿到一份专属的加密包」这个大白话版本就够用了。
要点
**群聊端到端加密 = 发送者密钥(一次加密、全群复用)+ 群成员各自的公钥(只用于首发时分发这把对称密钥)+ 棘轮演进(每条消息换锁)+ 进出群时换钥匙(管住前向和后向保密)。一句话总结:先把同一把钥匙挨家挨户塞进各自的专属信封,之后所有人共用一把锁,每开一次门就换一把新锁。**
服务端能看见什么、看不见什么
一封信的旅程:端到端加密的「分界线」
上一节我们把群聊的端到端加密讲完了——现在我们可以跳出来站高一点,看看**整条消息链路上,每个角色到底能看见什么**。这件事特别关键,因为它直接决定端到端加密「保护你到什么程度」「不保护你到什么程度」。
先用最生活化的一个类比:普通短信就像**贴了邮票的明信片**——邮递员、邮局、分拣中心全程都能看见你写了什么,服务器就是个透明邮局。**端到端加密则像把信装进了带锁的保险箱**——快递公司、仓库、分拣员全程只见一个铁皮箱子,看不见里面装了什么,但**他们还是知道这个箱子是谁寄给谁、什么时候寄的、有多重**。这就是「端到端加密」这几个字背后真正的边界。
三个视角,一条消息的完整旅程
我们把一条消息从你打字到对方手机显示,中间经过的「三双眼睛」画出来:
flowchart LR
subgraph 你的手机[你的手机客户端]
A1[明文消息<br/>今天 7 点开会]
A2[用会话密钥加密]
A3[密文 + 元数据<br/>时间 长度 收件人]
end
subgraph 服务端[传输信道与服务端]
B1[服务器看见密文]
B2[看见元数据<br/>谁发给谁 几点几分 消息多长]
B3[看不见明文内容]
end
subgraph 对方手机[对方手机客户端]
C1[收到密文 + 元数据]
C2[用会话密钥解密]
C3[还原成明文<br/>今天 7 点开会]
end
A1 --> A2 --> A3
A3 -.传输.-> B1
B1 --> B2
B2 --> B3
B1 -.传输.-> C1
C1 --> C2 --> C3
style A1 fill:#ffe1e1
style A3 fill:#e1e1ff
style B1 fill:#fff4e1
style B2 fill:#fff4e1
style B3 fill:#f0f0f0
style C3 fill:#e1ffe1
注意这张图的**关键边界**就在中间那一栏——服务端能看见和不能看见的,是泾渭分明的两块。
服务端能看见什么(明摆着的)
服务端在整条消息链路上,**始终盯着这些**:
- **密文本身**:就是那一串看上去乱码的字符,但服务端**没有钥匙**,解不开
- **发送者是谁**:你的账号、设备 ID
- **接收者是谁**:对方的账号、设备 ID
- **发送时间**:精确到秒
- **消息长度**:多少 KB、多少字节
- **消息数量**:一天发了多少条、频率怎样
- **IP 地址**:你从哪个网络连进来的
- **在线状态**:你现在是否在线、最后活跃时间
- **设备信息**:你用的是 iPhone 15 还是小米 14
这些东西合起来有个专业名字,叫**元数据(Metadata)**——「关于消息的信息,但不是消息本身」。
服务端看不见什么(这是端到端加密真正守住的)
服务端**打死也看不见**的是:
- **明文内容**:你发的「今天 7 点开会」「宝宝我爱你」「合同金额 50 万」——一个字都看不到
- **图片、语音、视频的内容**:就算你发了一张自拍,服务端只看见一堆乱码字节流,看不见你的脸
- **文件内容**:你传的 PDF、Word、Excel,里面写什么服务端不知道
为什么?**因为加密在客户端完成、密钥在客户端保管。** 消息一出你的手机就已经是密文,到达对方手机才被解开。中间这一整段路程上,没有任何一个节点同时拥有「密文」和「钥匙」——服务端手里只有前者,钥匙在两个客户端手里。
元数据本身也够敏感
这里有个**反直觉的真相**你得知道:**就算服务端看不见你说了什么,光凭元数据也能推断出很多**。举几个真实场景:
- **「谁和谁在联系」**这张社交关系网——往往比消息内容还值钱。警察查案、商业竞争、政敌摸底,第一步都是先画这张图
- **「消息发送的时间规律」**——比如每天晚上 11 点准时给某个人发消息,那大概率不是普通同事
- **「消息长度」**——如果两条消息都是 1.2KB、间隔 3 秒,可能是语音转文字
- **「突发性大量消息」**——突发事件、游行、灾难发生时,服务器能立刻知道「某地某时突然活跃」
**所以记住一句话:端到端加密保护的是「内容」,但不保护「通信模式」。** 黑客、警方、运营商、服务商,他们拿不到你说了什么,但**你跟谁聊、聊得多频繁、几点聊、聊多久——他们全知道**。
真实 App 在这条边界上的表现
| 维度 | Signal | WhatsApp | Telegram 普通聊天 | |---|---|---|---| | 消息内容 | 服务端看不见 | 服务端看不见 | **服务端看得见** | | 群聊内容 | 服务端看不见 | 服务端看不见 | **服务端看得见** | | 元数据(谁、几点、多长)| 服务端能看见(Signal 努力最小化)| 服务端能看见 | 服务端能看见 | | 消息备份默认位置 | 端侧为主 | 服务端有备份 | 服务端是默认 |
**Telegram 的「秘密聊天」才用端到端加密**——默认的那些普通聊天和群聊,**服务端全程能看见明文**。这点跟 WhatsApp 完全不同,是 Telegram 最容易被误解的地方。
要点
**端到端加密是一条非常清晰的「分界线」:分界线这边(明文内容、媒体文件、文件附件),服务端统统看不见;分界线那边(元数据:谁、几点、多长、IP、设备、频率),服务端照样看得一清二楚。要真正隐私,光靠端到端加密还不够——你还需要关心元数据。**
学习笔记
即时通讯中的端到端加密全流程
第一次握手:预密钥、X3DH 与安全指纹
不在线难题
- DH(染色混合)需要双方同时在线,互发「半成品」才能合出共享秘密。
- IM 场景中对方常不在线(睡觉、坐飞机、地铁无信号),DH 第二步卡住。
预密钥(Prekey)机制
- 用户在线时提前生成一批「一次性信箱」,公钥(投信口)批量上传服务器,私钥(开锁钥匙)留在本地。
- 每个预密钥只用一次,用完即弃。
- 用户在线时批量补货,保证服务器上「挂锁」不断。
X3DH(扩展型三次 DH)
- 把 DH 拆成「可用预密钥代为完成」的形态。
- 涉及四把钥匙:
- Bob 留在服务器上的预密钥公钥(一次性)
- Bob 的身份钥匙公钥(长期不变)
- Alice 当场生成的一次性临时公钥
- Bob 周期性轮换的签名预密钥(证明预密钥确实是 Bob 上传)
- 三(或四)次 DH 计算揉成同一把共享秘密,Bob 不必当时在场即可算出与 Alice 相同的结果。
- 一句话:X3DH = 预密钥 + 身份钥匙 + 临时钥匙,多染几层颜色得第一把会话钥匙。
预密钥未解决中间人攻击
- 预密钥未解决中间人攻击,服务器上「Bob 的公钥」是否真为 Bob 仍需验证。
每次会话:混合加密与临时对称密钥
不能全程用公钥私钥的原因
- 非对称加密费 CPU;几 MB 照片、几百 MB 视频会卡死体验。
- 对称加密极快,代价是密钥如何安全送达。
混合加密(Hybrid Encryption)
- 第一步:用 Bob 公钥加密一把随机会话钥匙(几十字节)。
- 第二步:用会话钥匙对称加密真实消息(文字、照片、视频)。
- 数据结构:上层为「用 Bob 公钥锁住的会话钥匙」,下层为「用会话钥匙锁住的真实消息」。
- Bob 反向:私钥解出会话钥匙 → 解开原文;链路对服务器完全不可见。
为何要「临时」生成会话钥匙
- 共享秘密是数学上的「颜色」,会话钥匙是喂给加密算法的具体格式,二者需一次「提纯」转换。
- 临时性更安全:泄露只影响该段会话,不牵连历史。
- 原则:会话钥匙生命周期越短、越随机,泄露风险越小。
服务端视角
- 看得见:密文外观(随机字符)、消息长度、发送时间、收发双方。
- 看不见:任何文字、照片中的脸、视频中的帧。
- 同样明文发 100 次会得到 100 段不同密文,是加密算法 + 临时钥匙的必然结果。
双棘轮算法:每条消息换一把钥匙
为何还不够
- 三年 10 万条消息共用一把会话钥匙,一旦该钥匙被提取,全部历史密文瞬间变明文。
- Signal 协议家族(WhatsApp、Signal)做到每条消息单独一把钥匙,用完即弃。
棘轮(ratchet)意象
- 只能往一个方向拧的扳手。
- 每把新钥匙由上一把「单向演进」而来,拿到新钥匙无法反推旧钥匙。
单向函数与逐条换钥
- 第 N 条消息的钥匙 = 某种单向变换(第 N-1 条的钥匙)。
- 黑客偷到 K3 只能解第 3 条消息,解不出 K2 也解不出 K4。
「双棘轮」的两层分工
- 内层(对称棘轮):每条消息换一把钥匙,保证单条粒度安全。
- 外层(DH 棘轮):每完成一次一来一回对话,双方换一把根钥匙,用于生成后续消息钥匙的种子。
- 外层解决「长期窃听者顺藤摸瓜」:将来用什么钥匙不由过去单独决定。
前向保密与后向保密
- 前向保密(Forward Secrecy):今天的钥匙被偷,过去的消息依然安全(内层)。
- 后向保密(Post-Compromise Security):今天的钥匙被偷,将来的消息依然安全(外层)。
群聊里的端到端加密
人群发一条消息需用 50 个公钥各加密一次
- 50 人群发一条消息需用 50 个公钥各加密一次,流量、电量、带宽全吃不消。
发送者密钥(Sender Key)
- 分发阶段:Alice 临时生成一把对称发送者密钥,用 50 个成员各自的公钥分别包成 50 个专属信封,随首条消息发出。
- 复用阶段:50 人各自拆开自己信封,取出同一把发送者密钥;之后 Alice 每条消息只需用这把钥匙加密一次,一条密文 50 人都能解。
群聊里的棘轮与换锁
- 发送者密钥也需跟着棘轮往前走:每发一条消息用单向函数演化一次,50 个成员同步演化。
- 偷到今天这把只能解今天一条。
- 进群退群也要换钥匙:新成员进群时,剩下的成员要重新分发一次新的发送者密钥。
服务端能看见什么、看不见什么
端到端加密的边界
- 类比:普通短信像贴邮票的明信片(邮递员全程可见);端到端加密像把信装进带锁保险箱——快递公司只见铁皮箱子,但仍知道箱子是谁寄给谁、什么时候寄的、有多重。
你的手机客户端
- 你的手机客户端:明文 → 用会话密钥加密 → 密文 + 元数据(时间、长度、收件人)。
第 5 关 · 真实案例对比——Signal、WhatsApp、Telegram
能向他人讲清三家在端到端加密上的关键差异,破除常见误解,并理解「客户端开源」为何对 E2EE 安全性重要。
Signal 协议:行业公认的技术标杆
协议不是单一算法,是一套工艺流程
上一章我们学了端到端加密的几块零件:预密钥、X3DH、密钥交换、临时对称密钥……这些就像乐高积木。**协议(Protocol)就是把这些积木按特定顺序拼起来的一整套「工艺流程」**——告诉你第一步做什么、第二步做什么、对方不在线怎么办、每条消息怎么换新钥匙。
**Signal 协议**就是当前业内公认最完整、最受信赖的这套工艺流程。
谁提出的
2013 年前后,Moxie Marlinspike 和他的团队(公司叫 Open Whisper Systems)把过去零散的研究整合成一套完整方案,最早装在他们自家开发的 Signal App 里。2018 年前后,Signal 基金会成立,Signal App 转为非营利项目运营。
谁在用——别被名字误导
虽然名字叫「Signal 协议」,但它**不是** Signal 公司的专利,而是**公开的、任何人都可以采用**的工业标准。今天我们熟悉的好几款应用其实都在用它:
- **WhatsApp**:2016 年起所有单聊默认启用(基于 Signal 协议改造)
- **Facebook Messenger** 的「秘密对话」功能
- **Google Messages**(安卓默认短信应用)的 RCS 聊天
- **Skype** 的「私人对话」
- 当然还有原版 **Signal App** 本尊
可以理解为:Signal 团队开源了「业内最安全的快递流程图」,全行业都在照着画。
整体形象:三层零件的拼装
Signal 协议不是一个算法,而是**三个层次叠起来**的完整工艺:
flowchart TD
A[长期身份钥匙对] --> B[首次握手层 X3DH]
C[预密钥池 一次性投信口] --> B
D[一次性临时钥匙] --> B
B --> E[第一把会话钥匙]
E --> F[每条消息层 双棘轮]
F --> G[逐条更换的临时对称钥匙]
G --> H[密文]
第一层:长期身份
每人在注册时生成一对长期身份钥匙(公钥 + 私钥),相当于「我在 Signal 世界的身份证号」——公钥长期公开、私钥永不离身。
第二层:首次握手(X3DH)
双方第一次联系时,借助**预密钥**(对方提前挂在服务器上的一次性投信口)+ **身份钥匙** + **一次性临时钥匙**,多次「染色混合」算出**第一把共享会话钥匙**。这一层解决「对方不在线也能开始对话」的问题。
第三层:每条消息都换新锁(双棘轮)
光有第一把钥匙还不够——万一某次钥匙被偷看,所有历史消息都会被翻。所以 Signal 协议引入**双棘轮(Double Ratchet)**机制:
- **棘轮**:一种齿轮,每转一格换一档,转过的格子不能倒退
- **双棘轮**:两个齿轮同时转
- 一个齿轮:每发一条消息**换一把新钥匙**(发出去的消息用了就废)
- 另一个齿轮:每来一条消息**也换一把新钥匙**
- 双方齿轮同步转动,所以永远能对上;第三方就算截到一次,**也只能解开那一条**,前后的都解不开
一个具象类比
想象你去一家特别安全的银行租保险箱:
- **长期身份** = 你的身份证(证明「你就是你」)
- **X3DH** = 你第一次去,银行先给你分配一个**临时储物间**,你把钥匙放进去,对方随时来取——你不需要亲自在场也能交接
- **双棘轮** = 每次存取之后,柜门上的密码**自动换一串**,旧密码立刻作废。即使有人偷看你输入一次,下次密码已经变了
要点
**Signal 协议 = 长期身份钥匙 + X3DH(首次握手)+ 双棘轮(每条消息换新钥匙)三件套;它不是某个公司的专利,而是公开的工业标准,WhatsApp 等多家应用都在使用,是当前端到端加密领域的事实标杆。**
WhatsApp:基于 Signal 协议,但默认范围要看清
WhatsApp 装的是 Signal 协议的「内核」
上一节我们讲了 Signal 协议是端到端加密的工业标杆。WhatsApp 在 2016 年做了一个关键决定——**直接把 Signal 协议装进自己的消息系统**。从那时起,WhatsApp 单聊的每一条消息、每一次语音通话、每一个视频通话,都用 Signal 协议来加密。
2019 年,**群聊也默认升级为端到端加密**(之前群聊并不是)。所以今天你打开 WhatsApp 看到任何一个普通对话,消息从你手机出发到对方手机,中间任何中转点——运营商、Wi-Fi 路由器、WhatsApp 自己的服务器——都只能看到一串乱码。
默认范围:哪些自动受保护、哪些不受保护
这里有一个很多人会忽略的关键点:**「装了 E2EE」不等于「所有场景都自动 E2EE」**。WhatsApp 把 E2EE 默认覆盖到了核心聊天功能,但有几个重要场景是**例外**:
**默认受保护的(E2EE 自动开启):**
- 一对一文字聊天
- 群聊(2019 年起)
- 一对一语音 / 视频通话
- 发送的图片、视频、文档、位置
- 语音消息
**默认**不**受保护的(明文可能离开设备):**
- **云端备份**——这是最大的坑。你把聊天记录备份到 iCloud(苹果手机)或 Google Drive(安卓手机)时,**WhatsApp 默认是明文上传的**。苹果或谷歌的服务器理论上能看见这些消息原文,FBI 如果拿到合法搜查令也能拿到。**2021 年起**,WhatsApp 推出了「端到端加密备份」选项(在 设置 → 聊天 → 聊天备份 里可以打开),开启后备份文件本身也被加密,需要你设置一个 64 位密钥或自设密码。
- **多设备登录**——WhatsApp 现在支持「已关联设备」,电脑端、iPad 等可以独立登录。这里有个微妙的差别:每台关联设备都有一对独立的钥匙,**消息在设备之间同步时仍然是加密的**,但同步机制比单设备复杂。
- **商业版 WhatsApp Business API**——商家如果通过第三方云服务(比如某些客服 SaaS 平台)来收发 WhatsApp 消息,消息可能先在第三方平台解密、存储、再转发,**这时候就不在端到端保护范围内**。
- **投诉举报时**——如果你举报某条消息,WhatsApp 会**解密最近的几条消息**转发给审核团队,用来判断是否违规,这是用户协议里写明的。
用流程图看清「保护范围」的边界
flowchart LR
A[你的手机] -->|E2EE 保护| B[WhatsApp 服务器]
B -->|E2EE 保护| C[对方手机]
A -.->|默认明文| D[iCloud / Google Drive]
A -.->|路径复杂| E[关联的电脑或 iPad]
A -.->|举报时主动上交| F[WhatsApp 审核]
A -.->|商家用第三方| G[客服 SaaS 平台]
实线箭头 = E2EE 保护;虚线箭头 = 明文或可能脱离保护。
一个具体场景
你在 WhatsApp 跟朋友说:「明天下午 3 点去公司楼下见,新项目的事。」
- 这条消息**在传输中是端到端加密的**——运营商和 WhatsApp 看不到内容
- 但是!如果你没开「端到端加密备份」,**这条消息会原样躺在你的 iCloud 里**——苹果公司理论上能看到,FBI 拿到搜查令也能看到
- 如果你**开了**那个备份开关,iCloud 里的备份文件就是一堆乱码,钥匙只在你手机里
差别就这么大。同一个聊天功能,一个开关,决定你的隐私天花板在哪。
要点
**WhatsApp 的单聊和群聊默认就是端到端加密(基于 Signal 协议),但「云备份默认明文」「商家通过第三方平台收发」「举报时主动解密」这几个场景是已知例外——真正想保护隐私的用户必须主动开启「端到端加密备份」选项。**
Telegram:普通聊天并非端到端,仅「秘密聊天」是
一个常见的认知错位
很多人一听到 Telegram,第一反应是「听说它特别安全」——这句印象其实只对了一半。Telegram 的安全模型跟 Signal、WhatsApp 有一个**根本性的结构差异**:它默认的聊天模式,**不是**端到端加密。
这听起来像在帮 Telegram 揭短,但请先听我把这个区别讲完——理解了底层结构,你才能在以后跟人讨论时不被「安全」这两个字唬住。
两种完全不同的「加密」
上一块我们说过,WhatsApp 默认就是端到端加密,服务器是「瞎子邮递员」。
Telegram 的默认模型不是这样的。它走的是**客户端-服务器-客户端**的加密结构:
- 你发出的消息先加密一次,送到 Telegram 的服务器
- 服务器**可以解开**这层加密,看到明文内容
- 然后服务器再用另一把钥匙把消息重新加密,送给对方
- 对方解开第二层加密,收到消息
用人话讲:Telegram 的服务器在你的消息路径上,**是一个看得见内容的「中转站」**,而不是「瞎子邮递员」。
这跟 HTTPS 加密网站的原理其实是一样的。你在浏览器访问网银,浏览器和银行之间确实是加密的,黑客在外面截不到内容——但**银行自己的服务器当然能看见你的账户信息**。Telegram 默认的聊天就是这个层次。
那 Telegram 到底能不能端到端加密?
能。但它把这个能力**藏得很深**:
- 打开某个联系人资料页 → 找到「**秘密聊天**」(Secret Chat)按钮 → 手动开启
- 开启后,这一对一的对话**才**是端到端加密的,服务器看不到明文
- 关键限制:**秘密聊天不能用于群聊**;而且秘密聊天只在发起的那两台设备之间同步,不会出现在你的其他设备上
也就是说,绝大多数普通用户的绝大多数聊天——普通一对一、群聊、频道、订阅号——**走的都是「服务器能看见」的那条路径**。
用流程图看清两种结构
flowchart LR
subgraph Telegram默认
A1[你的手机] -->|加密| B1[Telegram服务器<br/>能看到明文] -->|重新加密| C1[对方手机]
end
subgraph Telegram秘密聊天
A2[你的手机] -->|端到端加密| B2[Telegram服务器<br/>只能看到乱码] -->|转发乱码| C2[对方手机]
end
subgraph WhatsApp默认
A3[你的手机] -->|端到端加密| B3[WhatsApp服务器<br/>只能看到乱码] -->|转发乱码| C3[对方手机]
end
注意看:**Telegram 默认和 WhatsApp 默认,是完全不同的两种结构**。
为什么这个设计选择会被混淆?
舆论场里关于 Telegram 的误解有好几层来源:
- **品牌印象的传染**——Telegram 的创始人 Pavel Durov 在隐私问题上公开对抗过俄罗斯政府、有过「拒绝交出密钥」的故事,这些故事塑造了「Telegram = 隐私标杆」的形象。但品牌故事的浪漫,跟默认技术结构的安全等级,是两回事。
- **「秘密聊天」这个按钮的存在**——它让用户以为「Telegram 整体是安全的,必要时再开个秘密聊天」。但绝大多数人**不会**主动去开,因为默认能用、能跨设备同步、能搜历史——秘密聊天反而「不好用」。
- **媒体的笼统表述**——不少科普文章会写「Telegram 是一款主打安全的聊天软件」,而不区分默认模式和秘密聊天模式。
Telegram 自己的理由
Telegram 的官方说法是:**「我们想要跨设备同步、无限云端历史、可搜索的消息、大型群组——这些功能都需要服务器能看见内容。为了这些功能,我们选择放弃默认的端到端加密。」**
这是真实的工程权衡,不是借口。但权衡归权衡,**用户必须知道这个权衡存在**——否则你以为自己用的是「Signal 那种级别」的加密,实际却把内容放在了 Telegram 的服务器上。
一个具体场景
你在 Telegram 普通群聊里讨论公司新项目,提到「下周发布会场地换到 B 酒店」。
- 这条消息**在传输中是加密的**——路上的黑客截不到
- 但 Telegram 的服务器**看得到**「B 酒店」三个字
- 如果某个国家的执法机构找 Telegram 索要数据,理论上能拿到
- 这跟你用 Signal 或者 WhatsApp 默认聊天的保护等级,**不是同一档**
要点
**Telegram 默认的聊天是「客户端-服务器-客户端」加密,服务器能看见明文;只有手动开启的「秘密聊天」才是端到端加密,且不支持群聊。「Telegram 整体是端到端加密的」是对它安全模型最常见的误解——品牌故事掩盖了默认结构。**
三表对比与「开源」为何重要
把三家摆到同一张桌子上
前几块我们分别讲了 Signal、WhatsApp、Telegram 的端到端加密模型。分开讲的时候,每个的「结构特征」你可能都有了印象,但放到一起对照,差异才看得最清——这就是这一块要做的事。
我会先用一张横向对比表把三家摆开,然后**单独**讲表格里的一行:「客户端是否开源」——这一行不只是技术细节,它直接决定了你**要不要「相信厂商」**,是听完前三块后真正能用来判断一款聊天软件安不安全的关键逻辑。
横向对比表
| 维度 | Signal | WhatsApp | Telegram | |---|---|---|---| | 单聊默认是否端到端 | ✓ | ✓ | ✗(需手动开「秘密聊天」) | | 群聊是否端到端 | ✓ | ✓ | ✗(秘密聊天不支持群聊) | | 服务器能否看到明文 | 不能 | 不能 | 默认能(秘密聊天不能) | | 客户端是否开源 | ✓ | ✗ | ✓(但服务端闭源) | | 云备份是否受端到端保护 | ✓(自带加密备份) | ✗(iCloud/Google Drive 默认不含) | 不适用 | | 跨设备同步 | 需主设备在线 | 通过「关联设备」机制 | 原生多设备 | | 使用的协议 | Signal 协议(开源可审) | 基于 Signal 协议(但实现闭源) | 自有 MTProto 协议 |
> 表注:「✓/✗」是简化标记。WhatsApp 的备份其实可以选择「加密备份」,但**默认**的云备份**不**被端到端保护——这一点很多用户不知道。
逐行解读
**默认端到端的范围**
- Signal:所有聊天(1对1、群聊)默认都是端到端,没有「明文模式」可切。
- WhatsApp:单聊和群聊**默认**都启用端到端加密——这一点 Telegram 做不到。
- Telegram:只有手动开的「秘密聊天」才是;普通聊天和群聊都是服务器能看明文的。
**服务器能否看到明文**——这是「真·端到端」和「客户端-服务器-客户端」加密最核心的分水岭。Signal 和 WhatsApp 的服务器都是「瞎子邮递员」;Telegram 的服务器(默认情况下)是「看得见的中间人」。
**云备份**——一个很多人不知道的坑:**WhatsApp 默认的 iCloud/Google Drive 备份不是端到端加密的**。意思是,你平时聊天端到端了,但某天换手机从云备份恢复时,那条恢复出来的聊天记录明文躺在 Apple/Google 的服务器上。Signal 因为自带加密备份机制,没这个问题。
**跨设备同步**——Telegram 之所以敢用「服务器能看」的模型,部分原因就是为了**原生多设备**:你的手机、平板、电脑同时在线,所有消息实时同步,每个设备上都能搜历史。Signal 和 WhatsApp 为了保护端到端,要么需要主设备在线(Signal),要么用「关联设备」的机制(WhatsApp)。这是真实的工程权衡,不是 Telegram 偷懒。
「开源」这一行最重要,单独讲
对比表里有好几行,但「客户端是否开源」这一行我想单独拎出来讲,因为它直接决定了**你要不要「相信厂商」**。
「开源」到底意味着什么
「开源」的意思是:这个 App 的**源代码是公开的**,任何安全研究员、学术机构、竞争对手、好奇的开发者都可以下载下来**逐行审查**。
如果代码里偷偷藏了一个后门——比如「在某个特定条件下悄悄把消息明文复制一份发到别处」——开源意味着:
- 几千双眼睛在盯着,想藏东西的难度**极高**
- 一旦被发现,舆论和法律后果都是灾难性的
- 学术界会写论文指出问题,厂商必须回应
闭源则相反:只有厂商自己的人知道代码里写了什么。你**必须相信**他们没留后门、没在某个角落偷偷加一段把消息明文发出去的代码。
用「信任模型」来想这件事
flowchart TD
A[客户端闭源] --> A1[你必须相信厂商没留后门]
A --> A2[你必须相信厂商的服务器没偷看]
A --> A3[你必须相信厂商顶住了政府施压]
B[客户端开源] --> C[第三方安全审计可逐行验证]
C --> D[信任从相信厂商一家]
D --> E[转移到相信整个安全社区的眼睛]
三家在「开源」上的具体差异
- **Signal**:客户端**完全开源**,连服务器也是开源的(虽然服务器本身看不到明文)。这是「最不依赖信任」的模型。
- **WhatsApp**:客户端**不开源**。它使用 Signal 协议,但**实现是 Meta 自己写的、闭源的**。所以严格说:你信任的是「Meta 的工程师正确实现了 Signal 协议」——这个信任建立在 Meta 的工程声誉上,但**没法独立验证**。
- **Telegram**:客户端**开源**(所有平台都开源),但**服务器不公开**。这意味着你可以审计「我的手机是怎么加密消息的」,但你**不能审计**「Telegram 服务器拿到加密消息后到底做了什么」。
以后判断任何聊天软件,最该问的两个问题
听完整章后,**最该问的两个问题**是:
- **默认是不是端到端?**(决定服务器能不能看)
- **客户端是不是开源?**(决定你能不能独立验证「它真的做了它声称做的事」)
只有这两个问题**都**回答「是」,你才接近「无需信任厂商」的安全等级。
- **Signal**:在主流应用里是唯一**两个都是的**。
- **WhatsApp**:前者是、后者不是——你要信任 Meta 没在闭源的实现里偷偷改。
- **Telegram**:默认聊天连第一点都不满足,群聊也完全没有「端到端」可用。
要点
**端到端加密的「真实安全等级」取决于两件事:默认是否端到端、客户端是否可审计。Signal 在两点上都做到了,WhatsApp 在前者做到了但后者要信任 Meta,Telegram 在默认聊天上甚至不满足第一点。「开源」之所以重要,是因为它把「相信厂商一家」转化成了「相信整个安全社区的眼睛」——这是听完整章后真正可以用来判断的逻辑。**
常见误解与正确说法
为什么要先拆误解
学完前四块,你对 Signal、WhatsApp、Telegram 三家的差异应该有清晰的判断力了。但真正的考验不是「你自己懂」,而是「别人用错误的说法来反驳你时,你能稳稳地纠回来」。市场里关于端到端加密的**流行误解**比真相比起眼得多——微信群里、媒体报道里、朋友饭桌上都常听到。这一块就把最常见的五条拆开,每条都给你一句可以直接引用、转述给他人的**正确说法**。
误解一:「Signal App」就是「Signal 协议」
**误解**:很多人把 Signal 这款聊天 App 和 Signal 协议当成一回事,觉得「用 Signal 才用 Signal 协议」。
**正确说法**:Signal 协议是**一套加密协议**(即一套规则和算法),由 Signal 基金会开源。任何 App 都可以**采用**这套协议——**WhatsApp 就采用了 Signal 协议**(虽然是基于它的闭源实现)。换句话说:「Signal 协议」是工具,「Signal App」只是**众多使用这个工具的产品之一**。
> 一个直观的类比:TCP/IP 是网络协议,所有网站、App 都在用它,但「互联网」不等于「某一台服务器」。
误解二:WhatsApp 的聊天「全程」都是端到端加密
**误解**:WhatsApp 顶上写着「端到端加密」,所以云备份、跨设备同步、网页版登录等所有环节都受保护。
**正确说法**:WhatsApp 的**聊天消息传输**是端到端加密的(单聊和群聊默认都是),但**默认的 iCloud/Google Drive 云备份并不是**。WhatsApp 在 2021 年后提供了「端到端加密备份」作为**可选功能**,但**默认未开启**。这意味着:换新手机从云备份恢复时,恢复出来的消息是明文躺在 Apple/Google 服务器上的。
> 引用话术:「WhatsApp 聊天本身是端到端的,但云备份默认不是——要自己开那个『加密备份』开关才保险。」
误解三:Telegram 是「更安全的 WhatsApp」
**误解**:Telegram 在很多隐私圈被推荐,所以它的聊天都是端到端加密的。
**正确说法**:Telegram 的**默认聊天**是「客户端-服务器-客户端」加密,**不是**端到端——Telegram 的服务器**看得到明文**。只有**手动开启的「秘密聊天」(Secret Chat)**才是端到端,而且秘密聊天**不支持群聊**。所以「Telegram 更安全」是相对于其他无加密应用,对比 WhatsApp/Signal 在「默认范围」上其实是退步。
> 引用话术:「Telegram 默认不是端到端,群聊永远不是——只有单对单『秘密聊天』才是。如果对方说 Telegram 全程加密,他记错了。」
误解四:端到端加密 = 绝对安全
**误解**:只要是端到端加密,就没人能看到我的消息。
**正确说法**:端到端加密**只保护消息在「传输过程中」不被中间人看到**。它**保护不了**:
- **元数据**:谁在和谁聊、几点几分、聊了多久、消息多大——这些 Telegram、WhatsApp、Signal 的服务器**都能看到**,因为加密的是内容不是信封。
- **设备端**:你的手机如果被人解锁、被装了恶意软件、被偷了——加密帮不了你。
- **人**:和你聊天的人本身可能截图、转述、把你的手机给别人看。
- **云备份**:见误解二。
> 引用话术:「端到端加密防的是『传输途中被偷看』,不防『你自己手机被人打开』『和你聊的人截图』『谁和谁在聊』这些事。」
误解五:WhatsApp 和 Signal 一样安全,因为都用「Signal 协议」
**误解**:WhatsApp 既然用了 Signal 协议,那应该和 Signal 一样安全。
**正确说法**:WhatsApp 用了 Signal 协议(这也是事实),但**客户端不开源**——你看不到 Meta 工程师到底怎么实现的。理论上 Meta 可以在那个闭源实现里悄悄加一段后门,但因为代码不公开,**没人能独立验证**。Signal 的客户端是开源的,**任何人都可以审计**确认它真的只做了它声称的事。这是「两家都用同一种协议」和「两家都真正可信任」之间**最大的差距**。
> 引用话术:「用同一个协议和真正可信任是两回事——WhatsApp 客户端闭源,你必须相信 Meta 没在实现里动手脚;Signal 客户端开源,第三方能逐行验证。」
引用话术速查卡
| 误解 | 正确说法(一句话版本) | |---|---| | Signal App = Signal 协议 | 协议是工具,App 只是用了这个工具的众多产品之一,WhatsApp 也在用 | | WhatsApp 备份是端到端的 | 默认的云备份不是,要手动开「加密备份」才行 | | Telegram 聊天都是端到端的 | 默认不是;只有单聊「秘密聊天」是,群聊永远不是 | | 端到端 = 万无一失 | 它只防传输途中被偷看;元数据、设备端、人、备份都不在保护范围 | | WhatsApp = Signal 安全等级 | 用同一协议不等于可信任;WhatsApp 客户端闭源,没法独立审计 |
要点
**学完前四块你已经有了判断力,但要「对外讲清」还差最后一步:能识别并纠正市场里最常见的五条误解——Signal App 与协议的区别、WhatsApp 备份的坑、Telegram 默认非端到端、端到端并非万能、协议相同不等于可信任。这五条纠错话术就是你「向他人讲清」时最常会用到的弹药。**
学习笔记
真实案例对比:Signal、WhatsApp、Telegram
Signal 协议:端到端加密的工业标杆
**协议不是单一算法**,而是把预密钥、X3DH、密钥交换、临时对称密钥等积木按特定顺序拼起来的一整套工艺流程,规定第一步做什么、对方不在线怎么办、每条消息如何换新钥匙。
**来历**:2013 年前后由 Moxie Marlinspike 团队(公司 Open Whisper Systems)整合完成,最初装在 Signal App 里。2018 年 Signal 基金会成立,转为非营利运营。
**开源工业标准**:协议不是 Signal 公司的专利,而是公开的、任何人都可采用的工业标准。目前使用方包括:
- WhatsApp(2016 年起所有单聊默认启用)
- Facebook Messenger 的「秘密对话」
- Google Messages 的 RCS 聊天
- Skype 的「私人对话」
- Signal App 本身
**三层结构**:
- **长期身份层**:注册时生成长期身份钥匙对(公钥长期公开、私钥永不离身),相当于「在 Signal 世界的身份证号」。
- **首次握手层(X3DH)**:借助预密钥(对方预先挂在服务器的一次性投信口)+ 身份钥匙 + 一次性临时钥匙,多次混合算出第一把共享会话钥匙。解决「对方不在线也能开始对话」的问题。
- **每条消息层(双棘轮)**:
- 棘轮:齿轮单向转动,转过的格子不能倒退
- 双棘轮:发送和接收各转一个齿轮,每发一条/每收一条都换一把新钥匙
- 双方齿轮同步转动,第三方即使截到一次钥匙,**只能解开那一条**,前后的都解不开
**类比**:去银行租保险箱——身份证(长期身份)→ 临时储物间交接钥匙(X3DH)→ 每次存取后柜门密码自动换一串(双棘轮)。
WhatsApp:Signal 协议内核 + 默认范围要看清
**协议采用**:2016 年起把 Signal 协议装入消息系统;2019 年群聊也默认升级为端到端加密。
**默认受保护**(E2EE 自动开启):一对一文字聊天、群聊、一对一语音/视频通话、图片、视频、文档、位置、语音消息。
**默认不受保护**(明文可能离开设备):
| 场景 | 情况 | |---|---| | 云端备份 | 备份到 iCloud/Google Drive 时**默认明文上传**,苹果/谷歌服务器理论上能看见;2021 年起提供「端到端加密备份」选项,需在设置中手动开启 | | 多设备登录 | 关联设备各有一对独立钥匙,设备间同步仍加密,但机制比单设备复杂 | | WhatsApp Business API | 商家经第三方云服务收发时,消息可能被先解密再转发 | | 投诉举报 | WhatsApp 会解密最近几条消息转交审核团队 |
**典型场景**:聊天内容在传输中端到端加密;但若未开启加密备份,聊天记录会以明文躺在 iCloud 里;开启后备份文件就是乱码,钥匙只在本机。
Telegram:默认并非端到端,仅「秘密聊天」是
**认知错位**:很多人认为 Telegram「特别安全」,其实只对一半。
**两种完全不同的加密结构**:
- **Telegram 默认模式**:客户端-服务器-客户端加密,服务器能解开第一层看到明文,再重新加密转发
- **Telegram 秘密聊天**:手动开启后才是端到端加密
- **WhatsApp 默认模式**:端到端加密,服务器是「瞎子邮递员」
Telegram 默认的加密层次类似 HTTPS:浏览器和银行之间加密,但银行服务器本身能看见账户信息。
**秘密聊天的限制**:
- 必须手动在联系人资料页开启
- 不支持群聊
- 仅在发起的那两台设备之间同步,不出现在其他设备
**误解来源**:
- 创始人 Pavel Durov 公开对抗政府的形象塑造了「隐私标杆」印象
- 「秘密聊天」按钮存在让用户误以为默认安全
- 媒体笼统表述「主打安全」而不区分两种模式
绝大多数普通用户的绝大多数聊天(普通一对一、群聊、频道、订阅号)走的都是「服务器能看见」的那条路径。
三家横向对比
| 维度 | Signal | WhatsApp | Telegram | |---|---|---|---| | 单聊默认端到端 | ✓ | ✓ | ✗(需手动开秘密聊天) | | 群聊端到端 | ✓ | ✓ | ✗ | | 服务器能否看明文 | 不能 | 不能 | 默认能(秘密聊天不能) | | 客户端是否开源 | ✓ | ✗ | ✓(但服务端闭源) | | 云备份是否受端到端保护 | ✓(自带加密备份) | ✗(iCloud/Google Drive 默认不受保护) | 不适用 | | 跨设备同步 | 需主设备在线 | 关联设备机制 | 原生多设备 | | 使用的协议 | Signal 协议(开源可审) | 基于 Signal 协议(实现闭源) | 自有 MTProto 协议 |
**关键分水岭**:服务器能否看到明文——这是「真·端到端」与「客户端-服务器-客户端」加密的核心区别。
**云备份的坑**:WhatsApp 默认云备份不是 E2EE 加密的,恢复时聊天记录会以明文躺在 Apple/Google 服务器上。Signal 自带加密备份,无此问题。
**跨设备同步的工程权衡**:Telegram 之所以用「服务器能看」的模型,部分原因是为了原生多设备同步。Signal 和 WhatsApp 为保护端到端,要么需主设备在线,要么用关联设备机制。
「开源」这一行最重要
**开源的含义**:App 源代码公开,任何安全研究员、学术机构、竞争对手都可下载逐行审查。
**对 E2EE 特别重要的原因**:
- 闭源时,只有厂商知道代码里写了什么
- 开源时,想藏后门(如「特定条件下悄悄复制明文发到别处」)的难度极高
- 一旦被发现,舆论和法律后果都是灾难性的
- 学术界会写论文指出问题,厂商必须回应
开源不直接等于「一定安全」,但显著提高了透明度,使独立审查成为可能。
误解一
**误解一:「Signal App」就是「Signal 协议」**——两者不是一回事。Signal 协议是一套加密协议(规则和算法),由 Signal 基金会开源,任何 App 都可采用;WhatsApp 就采用了 Signal 协议(基于其闭源实现)。「Signal 协议」是工具,「Signal App」只是众多使用这个工具的产品之一。