跳转至

介绍 Signal 自动密钥验证

翻译备注:Signal 在 2026 年 8 月 11 日推出「自动密钥验证」(automatic key verification),底层技术是密钥透明度(key transparency)。既有的安全码(safety number)要当面或通过另一条可信渠道核对,自动密钥验证改由 App 自己去比对,省掉约时间见面的步骤。技术在通讯软件上还算新,Signal 这篇是少数把设计动机与运作方式一次说完的公开文件,因此先完整翻译,文末再附上编辑注解,说明它挡得住什么、挡不住什么。

以下内容原文翻译来自以下文章,主词角色为 Signal:

文末有编辑注解:译文结束后接着编辑注解,内容是 anoni.net 社群的补充,包含三条给非技术读者的结论、十三则说明、一节发布后的后续补充,最后是常见问题与延伸阅读。想先看社群观点的读者可以直接跳到那一节。

介绍 Signal 自动密钥验证

Signal 现在提供一项名为「自动密钥验证」的功能,用来补强既有的安全码机制。Signal 的通讯一律采端到端加密,自动密钥验证多提供一条简便的途径,让你确认端到端加密会话的两端之间没有非预期的第三方介入。

运作方式是由你、你的 Signal 联系人,以及第三方审计方各自执行一组验证,合起来提供与手动核对安全码相同的保证。与安全码相比,各项验证都是独立完成的,无需当面见面,也无需第二条通讯渠道。

整套验证机制确保电话号码或用户名与其公钥之间的对应关系,在 Signal 生态系统的所有参与者眼中都一致而且透明。可以防范的情境是密钥在拥有者不知情的状况下被替换,例如恶意方入侵 Signal,把另一把密钥挂到你联系人的电话号码上。

要实际操作,请进入某位 Signal 联系人的个人资料页,点「查看安全码」,再点「自动密钥验证」标题底下的「自动验证」按钮。功能可用而且验证成功时,按钮会显示绿色对勾与「加密已验证」。随着时间累积,你这一次的验证,加上联系人与第三方审计方持续执行的验证,共同确保该位联系人的密钥在整个 Signal 生态系统中保持一致。

Signal App 中自动密钥验证的界面

功能背后的概念称为「密钥透明度」(key transparency),后文都会使用这个词,说明我们为什么要建一套密钥透明度系统,并概述运作方式。

公钥与私钥入门

非对称密码学让你能传消息给朋友,而且只有朋友读得到。它牵涉到一对数学上相互关联的密钥,称为公钥与私钥,可以用在许多场合,收发消息是其中之一。

想象你有一个上锁的信箱,上面开了投递口。公钥像信箱的地址,可以给任何想寄信给你的人。私钥像信箱的钥匙,只有你持有,用它才读得到寄来的消息。任何人都可以把信投进你的信箱(用你的公钥加密),只有你能打开来读(用你的私钥解密)。信箱地址必须公开,没有人知道要寄到哪里,你就收不到信。

你注册 Signal 时,Signal App 会在注册流程中替你生成一组公钥与私钥1。私钥留在你的设备上,只有你能访问,Signal 不行,其他人也不行。公钥会送到 Signal,Signal 扮演所有用户公钥的中央目录。你要传消息给另一位 Signal 用户时,会向 Signal 索取对方的公钥,再用 Signal 返回的密钥与你的私钥把消息加密。

中间人 Mallory 攻击

传消息要先取得收件人的公钥,取得公钥就需依赖中央目录。理论上,恶意的目录运营者可以发动所谓的「中间人 Mallory」攻击,不过要办到,需要外部人士绕过主要云端供应商的安全防护,或由握有权限的内部人士刻意锁定特定账号。手法极为进阶,发生概率也很低,我们仍然想防住。以下沿用信箱的比喻,说明攻击在假设情况下如何进行。

假设 Bob 想寄一张喝咖啡的邀请给朋友 Alice,于是他到中央目录查她的信箱地址。目录若被对手(Mallory)攻陷,可能把 Bob 导向 Mallory 的信箱。Bob 把信寄到他以为是 Alice 的信箱,信实际上进了 Mallory 的信箱。Mallory 接着用自己的信箱钥匙取出 Bob 的信,读过内容,需要的话改写几句,换一个信封,再转寄到 Alice 的信箱。

Mallory 改写的内容可以是咖啡店的地点或碰面时间,让 Alice 前往错误的地点,或在错误的时间出现。Alice 看不出消息被拦截或篡改过,在她眼中,消息就是 Bob 直接寄来的。同一时间,Bob 会白等一场。就算 Mallory 选择不动 Bob 的内容,光是读得到,就已经构成通讯隐私的严重破口。

约咖啡出错的代价相对低,同样的攻击放到其他情境,造成的伤害会大得多。

中间人攻击的信箱比喻示意图

攻击能成立,是因为 Bob 从来没有真的验证过 Alice 的地址。他只是相信目录上列的信箱就是她的,而信任目录是个合理的假设。

Bob 若想格外谨慎,可以当面向 Alice 问地址,或通过另一条可信的通讯渠道问2。若 Alice 与 Bob 纯粹是笔友,这条路走不通。

那么,在无法见面、也没有第二条渠道的情况下,Bob 要如何验证 Alice 的地址?

本文接下来会说明我们如何设计出一套系统,让 Bob 无需直接联系 Alice,也能自动验证中央目录里的数据。

用比喻设计一套密钥透明度系统

要帮 Bob 确认目录里 Alice 的地址正确,一种做法是把目录的每一次变更都记录下来。有人改动目录里 Alice 的地址,就会留在按时间排序的日志里,因而可以被察觉。以下把信箱的比喻延伸下去,说得具体一点。

假设市立邮局里有一位职员,把每个人的地址变更都记在一本公开账本上。任何人换了新地址或更新既有地址,职员就在不断变厚的账本最后面加一页,把地址变更记在那里。职员用的是永久性的记号笔,写下去之后,没有人能翻回那一页撕掉或改内容。任何人都可以到邮局翻账本查地址,包括查自己的。

使用账本

对任何一笔地址,邮局的客户有两种方式跟账本互动:

  • 像 Bob 这样的客户,可以查别人(例如 Alice)的地址。
  • 像 Alice 这样的客户,可以查自己的地址,确认账本记得正确。

Bob 要找到 Alice 目前的地址,需从账本的最后一页开始,一页一页往前翻,翻到出现 Alice 的那一页为止。他从尾端倒着翻,是因为他要的是 Alice 最新的地址,而地址可能随时间变动过。账本页数越加越多,Bob 的工作量就越大,尤其在 Alice 有一阵子没更新地址、中间又夹着大量别人的地址变更需要一页页过滤的时候。

账本让 Alice 能验证自己的地址记得对不对,代价是她需把上次来访之后新增的每一页都看过,确认没有一页把她的地址写错。跟 Bob 一样,页数越多,工作量越重。

若 Alice 与 Bob 住在人口流动频繁的城市,大家常换地址,一页一页翻的工作量会大到不切实际。两人需要一种更有效率的方式来使用账本。

引入索引本

现实中的书常附一份按字母排序的索引,让读者快速找到要的内容。同样的想法可以套到账本上,做法是替账本至今收录过地址的所有人名,另外做一本按字母排序的索引本。

账本每加一页反映新地址或地址变更,索引本也要跟着更新,所以职员每往账本加一页,就发行一版新的索引本,内容涵盖截至那一页为止已被账本收录地址的所有人。长久下来,就形成一座对外开放的索引本馆藏。

索引本随账本页数逐版发行的示意图

先假设对账本的任一页,Alice 与 Bob 看到的一定是同一本索引本。下一节会谈到系统里的另一个组件,让两人能验证这项假设。

有了上述结构,Bob 可以改用「二分查找」的策略在账本里查 Alice 的地址,轻松许多,用具体例子最好说明。

假设一段时间内有 100 笔新增或更新的地址,账本因此有 100 页,职员也发行了 100 个不同版本的索引本。为了简化,假设 Alice 的地址只在账本里出现过一次,就是她刚搬来的时候。

Bob 先翻到账本的中间,接着查对应那一页的索引本。索引本按字母排序,找人名很快。若 Alice 的名字在那本索引本里,代表两种可能,它或许就是第一本收录 Alice 的索引本,也或许第一次出现在更早的版本,也就是账本更前面的某一页。

两种可能都让 Bob 可以忽略账本的后半段,改在前半段重复同样的步骤,直到找出 Alice 地址变更所在的那一页为止。更精确地说,Bob 的查找会在找到相邻的两本索引本时结束,前一本没有 Alice 的地址,后一本有。

查找流程有几个好处,第一个是有效率。账本若有十亿页,最坏的情况原本要倒着翻完十亿页,现在 Bob 最多只需要检视 30 页就能找到 Alice 的地址,工作量比先前轻松太多。

Alice 仍然想确认职员没有新增任何把她地址写错的页面,不过她无需检查每一页账本与每一本索引本。她只需要检查 Bob 为了找她地址而查过的那几页,如此就能确保 Bob 查到的 Alice 地址经过 Alice 本人验证。

由此带出查找流程的第二个好处:Alice 与 Bob 面对页数相同的账本时,流程是确定性的。职员若在 Bob 与 Alice 两次查找之间又加了页,情况会复杂一些,主要的概念不变。账本有十亿页时,Alice 可以照着 Bob 的查找流程走一遍,查 Bob 查过的同一批页面,确认里面没有任何一页把她的地址写错。

借由对查找流程取得共识,Alice 与 Bob 建立起一套使用账本的方式,让各自的目标在实际上可行。账本持续变厚,Bob 仍然有有效率的方法找到 Alice 的地址,Alice 也有有效率的方法确保 Bob 找到的地址正确。

为了说明清楚,上面的比喻做了简化。实际上 Alice 可以多次更新地址,要支持这种查找,索引本里要存的数据也不只有人名。我们已经把同样的想法实现到 Signal 的消息服务上,做成开源的密钥透明度服务器

职员本身呢

到目前为止,查找流程的描述都假设 Alice 与 Bob 亲自翻账本、查索引本。实际上并不可行,账本与索引本的体积远超过两人能直接处理的范围。实际做法是 Alice 与 Bob 请职员代为查找,再汇报结果。

但邮局可能已经被 Mallory 这类对手攻陷,由她假扮职员,最终目的是让 Bob 误以为 Alice 的地址实际上是 Mallory 家。所以 Alice 与 Bob 无法单纯信任职员,必须有办法自己独立验证查找流程。

做法是请职员把查找过程中查过的那些账本页面与索引本数据全部交回来,两人自己再核对一次。

核对要有意义,前提是职员交回来的数据可信,于是浮现一个明显的问题:假扮职员的 Mallory 若对记录内容说谎怎么办?举例来说,Mallory 可以私下另外维护一本账本,里面把 Alice 的地址记错,或者对账本的同一页发行两个不同版本的索引本。Mallory 可以把其中一套数据给 Alice,另一套给 Bob,让两人各自验证手上的数据,却察觉不到 Mallory 的把戏。

Alice 与 Bob 需要一位独立的见证者,让职员不敢造假。

第三方审计方

要阻止 Mallory 给 Alice 与 Bob 不同的数据,两人需仰赖第三方审计方。审计方的角色像公证人,在职员一页一页往账本加、一版一版发行对应索引本的时候,就站在旁边盯着看。

审计方会检查每一版索引本是否与前一版包含完全相同的数据,只差在多出的那一笔,以及职员没有移除或偷偷改动账本里先前的任何一页4。条件都成立时,审计方就替那一页账本与那一版索引本签名3,表示记录新增正确。

审计方对每一页与每一本索引本只会签名一次,所以职员若想把第 50 版索引本的不同版本分别展示给 Alice 与 Bob,只有其中一个版本拿得出有效的审计方签名。通过检查与验证审计方签名,Alice 与 Bob 可以确信职员只维护一本账本与一套对应的索引本,两人看到的是同一批记录。

在 Signal 的密钥透明度实现中,由 CloudflareTrail of Bits 担任受信任的第三方审计方。

监测

第三方审计方确保职员给 Alice 与 Bob 的是同一批数据,却无法验证记录内容本身正确。举例来说,Mallory 可以试着往账本加一页,列上一笔伪造的 Alice 地址变更。从审计方的角度看,只要 Mallory 正确地新增账本页面、也发行了新版索引本,就算一次合法的变更。可是 Bob 到账本查 Alice 地址的时候,会找到那笔假记录,并且相信它是 Alice 的真实地址。

监测的作用就在补上这一块,回想客户跟账本互动有两种方式,查别人的地址,以及查自己的地址。监测要求 Alice 与 Bob 定期做这两件事,各自能检测到一种不同的篡改。

Alice 监测自己在账本里的数据,做法是定期查阅并验证自己最新的地址记录。若查到预期外的地址,她应该通过另一条可信渠道通知 Bob,说他收到的地址不可信。

Bob 也必须定期查 Alice 最新的地址,确认与先前收到的一致。之所以重要,是因为 Mallory 塞进一笔假的地址变更之后,可能再补一笔把 Alice 的正确地址还原,借此掩盖痕迹。

从 Bob 的角度,查到 Alice 换了地址跟一次合法的搬家看起来一模一样,而合法搬家是常见得多的解释。即使如此,他仍然应该通过第二条渠道向 Alice 确认她真的搬家了。若没有,先前那个地址就应当成不可信。

Alice 按固定节奏做自我检查,Bob 依自己的步调查账本,两人都无法保证在 Mallory 介入的当下就抓到。但两种监测加上第三方审计,构成一套完整的检测机制:审计保证 Alice 与 Bob 看到的是同一份数据,监测保证两人都定期检查数据的正确性。合起来,Mallory 的篡改终究会被发现。

回到 Signal 本身

那么,以上种种跟 Signal 的密钥透明度如何对应?

在 Signal 里,你可以选择让别人用电话号码找到你,也可以建立用户名,让别人用名称找到你。决定开放电话号码或用户名之后,别人就能在 Signal 输入你的号码或名称,发起消息邀请。Signal 保有一份中央目录,最终把这些公开标识符对应到用户的公钥,就像信箱比喻里的「姓名」与「地址」。

Signal 用户注册、变更电话号码或用户名、重新建立账号时,Signal 会把变更记在一棵日志树(也就是「账本」)里,并用前缀树(也就是「索引本」)协助在日志树中查找。CloudflareTrail of Bits 各自担任两种树的独立审计方,两种树合起来构成密钥透明度日志。

日志里所有的用户数据都经过密码学处理而无法辨识,公开标识符会先通过可验证随机函数,标识符对应到的值则由带密钥的哈希函数保护,因此审计方从来看不到任何明文的用户数据。

你的 Signal App 会自动、定期检查日志里属于你自己的公开标识符,要验证联系人的标识符则必须从「查看安全码」画面发起。所有向日志查询标识符的请求都不带身份验证,因此不会跟特定用户账号绑在一起。

本文不深入实现细节,有兴趣的读者可以到我们的开源仓库查看。实现依据的是 IETF 密钥透明度协议的早期草案,并针对 Signal 的使用情境做了调整。

密钥透明度目前的实际样貌

密钥透明度显示,Signal 生态系统里所有设备对「标识符与其公钥的对应关系」抱持同一份视角。它不验证掌控某个电话号码或用户名的人究竟是谁。具体来说,Alice 与 Bob 可以通过密钥透明度检查,确保各自持有某个账号正确的公钥,若 Mallory 已经完全接管 Alice 的账号,要察觉仍需仰赖额外的验证,例如在安全码变动后主动追问。

目前你的 Signal App 会自动验证日志里属于你自己的电话号码与用户名数据。要替别人做同样的验证,你必须有对方的电话号码。也就是说,你若是通过用户名在 Signal 上与某人建立联系,彼此没有交换电话号码,也无从得知对方的号码,就无法验证对方。

符合以下任一条件,你手上大概就有 Signal 联系人的电话号码:

  • 你当初是用「以电话号码寻找」的选项,在 Signal 上开启与对方的对话。
  • 你的手机通讯录里存有对方的联系信息(而且对方在 Signal 选择开放以电话号码被找到)。
  • 对方选择了让所有人都能看到自己电话号码的设置(默认是没有人看得到)。

请记得,只有在对方存在你的手机通讯录里,或对方把电话号码的可见度设成所有人时,Signal 才会在 App 内显示对方的电话号码。

另一种情况是你手上的电话号码过期了,因为 Signal 上的联系人换了号码。换号码对联系人的公钥与底层的加密消息会话没有任何安全影响,却会让你无法对该位联系人使用自动密钥验证,原因是你手机里留着对方的旧号码,与账本中最新的电话号码记录对不上。情况类似监测那一节提到的,Bob 查到的 Alice 地址与先前收到的不同。极可能是一次合法的变更,你的设备却分辨不出它与服务器干扰的差别,所以你应该通过另一条可信渠道向联系人确认。

基于隐私优先的默认,上述情况我们一律让自动密钥验证无法使用,并建议用户改用既有的安全码机制,通过扫描 QR code 或比对一长串验证号码,手动确认自己与特定联系人持有同一组密钥。用户若倾向不依赖任何第三方,包含 Signal 与审计方在内,可以依序打开设置的「隐私」、「高级」、「自动密钥验证」关闭功能,继续使用手动的安全码验证。

结语

密钥透明度提供一种容易上手的方式,让用户确认消息安全中重要的一环,补足既有的安全码机制。

这项工作集合了 Signal 内部与外部的大量协作,我们特别感谢 Cloudflare 与 Trail of Bits 担任独立审计方。感谢他们,也感谢生态系统里许多让工作得以成真的人。


编辑注解

以下为 anoni.net 社群补充,非 Signal 原文内容

原文的比喻写得完整,技术脉络与取舍留在文外。以下先给三条结论,接着十三则补充,再一节发布后的后续补充,最后是常见问题与延伸阅读。

只想知道结论的话

以下三条不需要理解背后的机制,转述给没有技术背景的人也不会失真:

  • 绿色对勾代表号码对应到的密钥在整个 Signal 生态系统里一致,代表不了对方是本人。
  • 收到「安全码已变更」的通知就停下来,换一条渠道确认过再继续谈敏感的事。
  • 每隔一段时间打开设置里的「已关联设备」,看清单上有没有你不认得的项目。

日常使用看完上面三条,再看接下来四则就够。需要保护消息来源、在组织里管对外账号、经常跨境或设备可能离开视线、加害者可能就在身边的读者,往后几则是为你们写的。最后三则谈密钥透明度怎么设计出来,不影响操作。发布之后另外补了一节,谈审计链的形状、对勾会被读成什么、匿名查询的双向性,以及可验证性到哪里为止。

绿色对勾保证什么,不保证什么

原文在「密钥透明度目前的实际样貌」一节已经划出界线,换个说法再说明一次会更清楚。自动密钥验证只确认一件事,同一个标识符在整个生态系统里对应到同一把密钥。握着那个电话号码或用户名的人究竟是谁,功能本身管不到。

常见的几个问题逐项对照。

你想确认的事 自动密钥验证 该看哪里
服务器有没有偷换某个号码对应的密钥 可以 绿色对勾
对方是不是本人 不行 安全码变动通知,另一条渠道追问
有没有陌生设备挂在你的账号上 不行 设置里的「已关联设备」
群组成员的密钥有没有被换过 不行 对每个人各做一次一对一验证
手机本身有没有被动过手脚 不行 属于设备安全,不在功能范围
号码的控制权在谁手上 不行 注册锁定 PIN,必要时拨 113

账号被接管的情境下,界线会变得很尖锐。攻击者若拦截到短信验证码、完成 SIM 卡调包,或取得对方已解锁的手机,可以用同一个电话号码重新注册 Signal。重新注册会生成新的身份密钥,而新密钥由服务器循正常流程写进日志,算一次合法变更,审计方不会有意见,日志前后也一致。此时你对那位联系人执行自动验证,画面仍会显示绿色对勾与「加密已验证」,只是验证通过的对象已经换人

对方的身份密钥改变时,Signal 会在对话中以安全码变动通知标示出来,真正的警讯留在那一条。自动密钥验证不取代安全码变动通知,两件事回答不同的问题。

只作用在一对一,群组没有自动验证的入口

原文的操作说明是进入某位联系人的个人资料页,Signal 设置里的说明写得更直接:「如果启用此功能,Signal 会尝试自动验证一对一聊天加密。」群组聊天没有对应的入口。

限制来自密钥透明度的设计,日志记录一个标识符对应到哪一把密钥,而群组不是一个标识符,它是一群各自持有密钥的人。要确认一个二十人群组里每个人的密钥都没被换过,等于对二十个人各做一次一对一验证,每一次都需要你握有对方的电话号码。

把 Signal 群组当成协作骨干的社群,务实的做法是分层。核心决策的少数几人值得逐一验证,人数多、流动快的执行层改用社会性的确认,由信任的人亲自介绍、当面拉进群组。站上的社运行动者的数位准备有更完整的分层设计。

查证来源(2026-08):values-zh-rCN/strings.xml - Signal-Android,字符串 preferences_automatic_key_verification_body

关联设备是它看不到的地方

Signal 的关联设备(linked device),也就是桌面版与 iPad 版,与手机共用同一把身份密钥。攻击者若诱使你扫过一次恶意的关联 QR code,他的设备会挂进你的账号、同步收到后续消息,而你的身份密钥完全没有改变。安全码不变,日志里不会多出任何一页,密钥透明度从头到尾看不到,绿色对勾会一直亮着

2025 年 2 月 Google Threat Intelligence Group 记录了实际的攻击。针对乌克兰军方人员、政治人物与记者的攻击者,把设备关联用的 QR code 伪装成 Signal 群组邀请页面,或乌克兰军方使用的应用程序页面,诱导目标把攻击者的设备连上自己的 Signal 账号。报告的说法是,攻击成功之后消息会即时同步给受害者与攻击者双方,形成持续窃听的通道,过程中不需要完整攻陷设备。

对应的操作是定期打开设置里的「已关联设备」,确认清单上每一项你都认得。密钥透明度不会替你看已关联设备。至于要不要解除不认得的关联、什么时候解除,在加害者可能就在身边的情况下需要先想过后果,后面「对方就在你身边时」那一则会谈到。

查证来源(2026-08):Provisioning.proto - Signal-Android,ProvisionMessage 带有 aciIdentityKeyPrivate,关联新设备时主设备会交出账号的身份私钥。
查证来源(2026-08):Signals of Trouble: Multiple Russia-Aligned Threat Actors Actively Targeting Signal Messenger - Google Threat Intelligence Group,2025-02-20。

在台湾与周边的脉络

台湾的手机号码采实名制,号码与身份证件绑在一起,补办 SIM 卡并同时取得短信验证码的攻击路径比想象中短。账号被完整接管时自动密钥验证会照常显示绿色对勾,所以更该优先打开 Signal 的注册锁定,设一组只有你知道的 PIN 码,让别人光有号码无法重新注册你的账号。注册锁定的优先顺序排在逐一验证联系人之前。整体的防护顺序见站上的一般人平常该做到什么,自动密钥验证算是锦上添花的一层,密码管理器与两步验证仍然排在更前面。

在 Signal 被封锁的地区,第一个问题是功能能不能用。密钥透明度的查询跟其他 Signal 功能一样需要连得上 Signal 的服务器,连线被挡住或不稳定的时候查询完成不了,验证就不会成功。Signal 没有说明「连不上」与「验证失败」在画面上如何区分,可行的判断方式是先看整个 App 收发消息正不正常,正常的话问题比较可能出在验证本身。查询不带身份验证,日志看不出是谁在查,走代理或审查规避工具时,通道的运营者仍然看得到你在跟 Signal 通讯,各种通道把可见度换到谁手上,见站上的 VPN 的风险与选择

原文提到你手上留着联系人的旧号码时,自动密钥验证会直接无法使用,反过来,你换了号码之后,联系人的通讯录里留着你的旧号码,他们同样验证不了你,影响往两个方向都成立。跨境移动、常换预付卡或 eSIM 的人,两个方向都会频繁遇到,算是常态。退路仍然是安全码,当面扫 QR code 最快,只能通过语音核对那串数字时,前提是你认得对方的声音。维持多组号码与多个账号的人,每个账号的自我检查各自独立,站上的怎么维持多个网络身分谈到相关的取舍。

篡改终究会被发现,但不会当场被挡下

原文的监测一节写得含蓄,密钥透明度能检测篡改,没有即时阻挡的能力。Mallory 在账本里塞一笔假记录的当下,Bob 的查询仍然会取得假密钥,消息仍然会被读走。真正的保障来自 Alice 下一次自我检查时会发现对不上,而审计方的签名让 Mallory 无法对 Alice 与 Bob 各说一套。攻击窗口因此落在「从篡改到下一次监测之间」,代价则是必然留下可审计的证据。对长期监控来说,会留下证据往往就足以吓阻。

你打开自动验证之前送出的内容,期间若发生过密钥置换,那些内容已经走在错的通道上,功能不会回头修补,保护的方向只有往后。发现异常之后只能评估损害范围,判断哪些内容可能已经外流,以及对方是否还是本人在操作。

你的 App 自己检查,验证联系人要手动

原文提到你的 Signal App 会自动、定期检查日志里属于你自己的电话号码与用户名,验证联系人的标识符则必须从「查看安全码」画面手动发起。两件事的节奏差很多。

原文写「随着时间累积,你这一次的验证,加上联系人与第三方审计方持续执行的验证,共同确保该位联系人的密钥在整个 Signal 生态系统中保持一致」,容易被读成关系要够久才有保障。拆开来看,审计方审计整份日志,跟你们认识多久无关。你与对方各自的自我检查绑在自己的账号上,也跟关系新旧无关。只有「你对某位联系人的验证」是一次性动作,而它按下去当场就生效。

临时组成的团队因此不必担心用不上,第一次见面交换到电话号码就能验,比安全码更适合陌生人快速建立联系,因为不需要另约时间。限制在别的地方,那一次验证只反映按下按钮那一刻的状态,不会自动延伸。任务型的用户若只在组队当天验过,等于把确认锁在风险最低的阶段,真正高风险的那几天没有覆盖到。做法是至少验两次,组队时一次,高风险窗口开始前再一次。

日常的用户可以把节奏改成事件驱动,收到安全码变动通知、对方换手机或换号码、对话内容出现反常的时候,回去看一眼。

要验证别人,需先有对方的电话号码

对匿名网络社群的读者而言,电话号码的要求是最需要留意的取舍。Signal 过去几年一直在降低电话号码的角色,用户名、默认不公开号码都朝同一个方向走。自动密钥验证目前的设计却要求你握有对方的电话号码才能验证对方,于是最在意隐私、只用用户名交换联系方式的那群人,恰好是暂时用不到新功能的一群。

站上的记者保护消息来源匿名通讯工具比较都建议用用户名交换联系方式,让消息来源不必先交出电话号码。照站上的建议建立起来的关系,记者手上通常没有对方的号码,自动密钥验证从一开始就用不上。取舍很明确,来源的身份保护排在前面,验证的便利性往后排。

功能也制造了一个诱因,让人为了让那个对勾出现,反过来去跟联系人要电话号码,属于要特别避免的误用。对方选择只给用户名,通常正是不想留下号码,为了验证去追问,等于把功能的便利性凌驾在对方自己的选择之上。验不了就接受验不了,高风险的个案改走当面或另一条渠道核对安全码。倡议组织面对捐款人与服务对象时尤其要守住,脉络见站上的倡议组织的匿名捐款管道

原文的叙事是 Bob 去验证 Alice,实际的信任链常常反过来。公开身份的人,例如记者、组织的对外窗口,被锁定的概率比多数联系人高,而看着绿色对勾决定要不要信任的,是来找你的那一方。你自己的账号没有守好,所有信任那个对勾的人会一起被误导。注册锁定与已关联设备的检查,优先顺序排在逐一验证每个联系人之前。

Signal 遇到限制时直接让功能不可用,选择是对的,宁可让按钮消失,也不要给出一个看起来成功、实际上没有意义的绿色对勾。纯用户名的联系人目前仍请沿用安全码,扫 QR code 那条路一直都在。只是当面核对本身也有代价,被看到跟某个人有联系,对还没出柜的伴侣或需要保护的消息来源就是一次额外的曝光。当面核对留给真正需要的时刻,例如收到安全码变动通知之后,不必变成常态。

账号背后换了人,密钥不会变

密钥透明度绑定标识符与密钥的对应,不绑定标识符背后是哪一个人。前面谈账号接管时,落差表现成攻击,在组织里则是日常运作的一部分。

对外窗口、客服、项目联系人等角色账号,操作的人会换。交接若做得规矩,沿用同一台设备,或用注册锁定的 PIN 重新注册,密钥完全不会变动,安全码也不会变。一年前验证过那个账号的人,不会收到任何技术讯号告诉他们操作的人换了。密钥透明度本来就没有要回答账号背后是谁在操作的问题。

角色账号还有两件事跟个人账号不同。第一,「已关联设备清单上每一项你都认得」那条建议假定只有一个人在管账号,多人轮值时要改成比对一份内部名册,靠记忆不可行。第二,组织号码的短信验证码可能不只一个人收得到,办公室转接线、IT 管理的 eSIM、账单持有人都可能在链上,注册锁定的 PIN 要当成组织的共用机敏凭证管理,存放与轮替的做法见站上的密码管理器入门

交接时要做的是换掉 PIN、盘点并清理已关联设备、记录目前谁握有管理权。若交接的情况不欢而散,处理顺序比照后面「对方就在你身边时」那一则。

设备离开你的视线之后

出入境查验、临检、设备被扣留一段时间再归还,三种情况有一个共同点,对手有过实体接触的机会。密钥透明度查服务器上的记录,与你的设备有没有被动过是两件独立的事,所以自动验证仍然会显示绿色对勾。

拿回设备之后要主动检查已关联设备清单,以及重要联系人的安全码有没有变动。清单干净只说明没有新的设备挂进你的账号,不足以推论设备本身没被动过手脚,那属于设备安全的范围。

被要求当场解锁交出,风险又高一层,对手取得你配合之下的完整访问权。保守的做法是把设备视为已暴露,重新评估账号的 PIN 码与重要联系人的验证状态。事前准备与事后处理的清单,站上的出差与研讨会的数位准备(东亚与东南亚)社运行动者的数位准备写得比较完整。任务型的通讯还要处理收尾,任务用的号码注销之前提醒还留着号码的人清掉,借用的设备归还之前先手动解除关联,别假设对方会自己发现,选务场景的整体准备见选举观察员的自保

对方就在你身边时

前面几则假定的攻击者都在远端,需要拦截短信验证码,或诱你扫一张恶意的 QR code。加害者若是同住的人、知道你的解锁方式,或本来就是号码的登记人与账单付款人,连前置动作都不必,因为对方看到的是你本人已经解开的画面,前面所有机制都绕不过去。

号码那一层要分开看,注册锁定挡得住「用你的号码重新注册 Signal」,挡不住对方对号码本身的行政控制权。对方若是合法的号码持有人,走电信商的正常渠道就能处理你的号码,过程中不需要伪造任何身份。设 PIN 码的时候也要留意,只有在对方不在场、不知情的状况下设定才有意义,并且不要与手机解锁码相同。未成年而使用家庭方案的人还要多想一层,号码、账单与设备管理往往在同一个人手上,设好 PIN 挡得住重新注册,挡不住对方看到你装了什么 App,设备层的痕迹管理见站上的 LGBTQ+ 与性少数的匿名社交

检查关联设备的建议,在同住的情境下要先想过后果。前面说看到不认得的项目就解除关联,那条建议假定对手是陌生人,解除之后不会再出现。加害者是同住者的时候前提不成立,被解除的那台设备会立刻失去访问权,对方下次打开就会发现,而「你发现了」本身可能升高风险。比较安全的顺序是先确认人身安全与手边可用的支持资源,需要时先保留画面记录,再决定要不要解除、什么时候解除。

原文反覆建议的「通过另一条可信渠道确认」也有同样的前提问题,长期被监控的人不一定有一条对方接触不到的渠道。台湾可以拨 113 保护专线做匿名咨询,由社工协助判断风险等级。更完整的准备见站上的家暴受害者的数位准备紧急求救

审计方本身也是一种信任

功能引进了两个新的外部角色,Cloudflare 与 Trail of Bits。两家都无法读到明文数据,公开标识符经过可验证随机函数处理,对应值由带密钥的哈希函数保护。审计方能确认日志前后一致、没有被回头改写,看不到日志里究竟是谁。

多一位独立审计方通常让信任假设变弱,从「必须相信 Signal 没有作恶」放宽成「至少要有一位审计方是诚实的」,方向要说清楚。客户端实际要求三份签名,Signal 自己运营一份,Cloudflare 与 Trail of Bits 各一份,缺任何一份都会跳警告、让自动密钥验证失败。每份签名有七天有效期,全恶意的服务器因此最多维持一周的分叉视图。原文只写了 Cloudflare 与 Trail of Bits 两家,第三份自签要看 Trail of Bits 自己的说明才知道,后面「后续补充」那一节接着谈。

完全不接受第三方假设的用户,Signal 留了关闭开关,设置路径在隐私、高级、自动密钥验证。关闭之后回到手动的安全码验证。

为什么标识符要先过一层可验证随机函数

原文提到公开标识符会先通过可验证随机函数(Verifiable Random Function),一句话带过,背后的取舍可以再说明。

日志必须公开才有办法被审计,公开的日志若直接列出电话号码,任何人都可以整份取回,做成一份「哪些号码注册过 Signal」的名单。换成一般的哈希函数也挡不住,电话号码的可能组合数量太少,逐一算过一遍就能还原。

可验证随机函数让服务器用一把只有自己知道的密钥,把标识符映射到日志里一个看起来随机的位置,同时附上一份任何人都能检查的证明,说明映射确实照规则生成。外人少了那把密钥就无法自行还原名单,审计方仍然验证得了日志的一致性。

「不带身份验证」的意思也要看清楚。原文说所有向日志查询标识符的请求都不带身份验证,因此不会跟特定用户账号绑在一起。不带身份验证只保证查询不会被绑到你的账号,不保证服务器不知道你查了谁。可验证随机函数的密钥在服务器手上,你要查某个标识符,就得把它送过去让服务器算出对应的位置与证明,被查的标识符本身服务器看得到,审计方读不到明文则是另一层设计。

密钥透明度不是 Signal 首创

概念上密钥透明度延伸自证书透明度(Certificate Transparency),把 HTTPS 证书的公开日志与审计机制搬到即时通讯的公钥上。学术脉络可以再往前拉,2015 年的 CONIKS 提出让用户自行监测目录的设计,2019 年的 SEEMless 补上隐私与效率,Meta 在 2021 年把相关想法做成开源的 Auditable Key Directory(AKD)程序库。

通讯软件的第一个大规模部署来自 WhatsApp,2023 年 4 月上线,底层用的就是 AKD,当时的定位是让任何人都能自行验证。Cloudflare 接手担任第三方审计方,是一年五个月之后的 2024 年 9 月,两件事常被压成同一件。Apple 的 iMessage Contact Key Verification 在 2023 年底推出,走另一条路线,由用户设备自己验证一致性证明。

IETF 的 KeyTrans 架构草案把部署方式分成三种模式,联系人监测(contact monitoring)、第三方管理(third-party management)与第三方审计(third-party auditing),差别在于由谁负责察觉日志分叉。草案本身只定义模式,没有点名哪一家系统落在哪一格,常见的对照表出自工作组简报与各家自己的说明。Signal 这次以第三方审计为主,同时要求客户端对自己的标识符做监测,互补的理由在原文的「监测」一节说得很清楚。

查证来源(2026-08):CONIKS: Bringing Key Transparency to End Users - USENIX Security 2015。
查证来源(2026-08):SEEMless: Secure End-to-End Encrypted Messaging with less trust - Chase、Deshpande、Ghosh、Malvai,ACM CCS 2019。
查证来源(2026-08):Deploying key transparency at WhatsApp - Meta Engineering,2023-04-13。AKD 程序库见 facebook/akd,仓库 2021 年 6 月建立。
查证来源(2026-08):Cloudflare helps verify the security of end-to-end encrypted messages by auditing key transparency for WhatsApp - Cloudflare,2024-09-24。
查证来源(2026-08):Advancing iMessage security: iMessage Contact Key Verification - Apple Security Research,2023-10-27。

后续补充(2026-08-13)

文章发布当天,Trail of Bits 也贴出自己那一侧的说明,里面有 Signal 原文没写的审计细节。以下四则按几位不同专业背景的读者的提问整理,查证日期都在 2026-08。

审计的独立性建立在跨组织,不在跨法律管辖

客户端要求的三份签名,分别由 Signal、Cloudflare 与 Trail of Bits 运营,三家都是美国实体。跨组织的分散做到了,跨法律管辖没有。一份强制令同时触及三个签名者,在美国境内是可以想像的路径,对身处与美国没有对等司法互助机制地区的用户,保证的实际强度目前没有先例可查。

Trail of Bits 照规格从头写了一套审计器,没有沿用 Signal 的参考实现,理由是独立实现才抓得到共病的错误,代码开源在 trailofbits/signal-auditor。他们也写明不向 Signal 或任何一方收费,两项选择让第三方审计不只是挂名。

现行设计把察觉日志分叉的责任交给少数几个审计方,学界对此有意见。2026 年的 MINGLE 提出让客户端在通讯时顺便交换彼此看到的日志状态,论文摘要直接点名现行部署把检测委托给少数第三方审计方,形成可被施压、被攻陷或无法持续审计的中心化瓶颈。Signal 目前没有客户端之间的交叉比对。

绿色对勾会被读成什么,空白又会被读成什么

安全指示器的既有研究显示,正面图示长期被读得比技术定义宽。工程团队写的是「标识符与密钥在日志里一致」,用户看到的是「这个人安全」。

2007 年一项针对网上银行的研究把用户原本设定的个人化安全图片拿掉,用自己账号操作的二十五人里有二十三人仍然输入了密码。预期中的正面提示消失,多数人不会提高警觉,多半根本没注意到。

自动密钥验证因为对方只有用户名或号码过期而不可用时,比较可能发生的是用户直接略过。空白不会自己变成警讯。

自动化研究反复观察到,手边有低成本渠道可以依赖时,需要主动投入的人工检查会系统性减少。验证变便宜之后,愿意约时间当面扫 QR code 的人只会越来越少,而当面核对正好涵盖自动验证覆盖不到的那一块,账号被完整接管的情境。

匿名查询的保护是双向的

查询日志的请求不带身份验证,设计目的是让服务器无法把查询绑回你的账号。同一个设计让查询你的人也享有一样的匿名。只要对方原本就知道你的电话号码,就能反复查询你的标识符在日志里的记录,观察你何时换机、换号或重新注册。过程不必碰你的设备,你也不会收到任何通知,原文没有描述任何会告知被查询者的机制。

前面「对方就在你身边时」那一则要再加一层:离开一段有控制关系的关系之后,对方手上通常还留着你的号码。换号码本身会在日志里留下一笔可被观察的变更,时间点对盯着看的人是有意义的讯号。

可验证性到你的手机就断了

审计方签的是服务器上那份日志的结构,签名不涵盖你手机里的 App 有没有诚实执行验证、画面上那个对勾有没有如实反映结果。那是另一条信任链。要核对手上的 App 与公开源代码一致,Android 版有可重现构建的流程与自动化检查,社群也有人持续重现 Play Store 的版本。iOS 版没有对应的构建说明,限制来自 App Store 的签署流程。

Cloudflare 在 2024 年为 WhatsApp 的审计做了一套任何人都能执行的复验工具,目前收录的仍是 WhatsApp 那组,没有 Signal 的对应项目。想自己复验 Signal 审计结果的研究者,现阶段需要从头做起。

查证来源(2026-08):How Trail of Bits helps verify the integrity of your Signal chats - Trail of Bits,2026-08-11。三份签名、七天有效期、审计器开源与不收费均出自此文。
查证来源(2026-08):Signal and Ready to MINGLE: In-Band Gossip for Key Transparency Split-View Detection in E2EE Messengers - IACR ePrint 2026/1010。
查证来源(2026-08):The Emperor's New Security Indicators - Schechter、Dhamija、Ozment、Fischer,IEEE Symposium on Security and Privacy 2007,论文摘要记为 25 人中 23 人。
查证来源(2026-08):trailofbits/signal-auditorcloudflare/plexi,后者的说明文档目前只列 WhatsApp 的 namespace。
查证来源(2026-08):Signal-Android 的 reproducible-builds 说明,Signal-iOS 仓库无对应目录。

常见问题

自动密钥验证要我自己去打开吗

不用。原文的写法是不想依赖任何第三方的人「可以在设置中关闭」,也就是默认就是开启的。开关在隐私、高级、自动密钥验证,是全局设置,不能逐一联系人控制。你自己标识符的检查由 App 在背景执行,不需要你操作。要验证某位联系人则要自己进去按,位置在对方个人资料页的「查看安全码」画面。原文没有提到最低版本需求,看不到按钮时先更新 App 再看一次。

打开自动密钥验证之后,还需要核对安全码吗

看对象。日常联系人可以只靠自动验证。面对高风险的对象,例如消息来源、律师、跨组织的敏感协作,当面扫 QR code 仍然是最强的一层,因为它不依赖 Signal 的服务器,也不依赖任何审计方。两种做法可以并存,自动验证负责日常的持续比对,手动核对负责一次性的高强度确认。

显示绿色对勾,代表对方一定是本人吗

不代表。绿色对勾说明你手上的标识符对应到的密钥,跟整个 Signal 生态系统看到的一致。对方的账号若已经被完整接管,攻击者用同一个号码重新注册生成的新密钥,同样会通过验证。判断对方是不是本人,仍要靠安全码变动通知、对话内容的异常,以及另一条可信渠道的追问。

群组聊天里的成员,可以用自动密钥验证吗

不行。Signal 设置里的说明写着「自动验证一对一聊天加密」,群组没有对应的入口。要确认群组成员的密钥,只能对每个人各自执行一次一对一验证,而且同样需要你握有对方的电话号码。人数多的群组不容易逐一做完,实际上建议只在核心的少数几人身上落实。

自动验证的按钮没有出现,是我操作错误吗

多半不是操作问题。最常见的原因是你手上没有对方的电话号码,例如你们是通过用户名建立联系的。另一种是你存的号码过期了,对方已经换号。Signal 在两种情况下一律让功能不可用,改请你使用安全码。

我验证了某位联系人,对方会知道吗

原文说所有向日志查询标识符的请求都不带身份验证,不会跟特定用户账号绑在一起。保证的范围到这里为止,查询不会被绑到你的账号,连接来源与时序仍然握在服务器手上,推不出服务器完全无从关联。原文也没有描述任何会通知对方的机制,同样没有正面交代,处境对此特别敏感的人,保守假设比较安全。

我换了新号码,为什么旧联系人验证不了我

因为对方的通讯录里留着你的旧号码,与日志中最新的号码记录对不上。限制是双向的,你验证不了持旧号码的人,持你旧号码的人也验证不了你。做法是通过另一条可信渠道告知新号码,等对方更新通讯录,或直接约时间扫 QR code 核对安全码。

我们是临时成军的团队,来得及用上吗

来得及。原文那句「随着时间累积」容易被读成关系要够久才有保障,但审计方审计整份日志,你与对方的自我检查各自绑在自己的账号上,都跟你们认识多久无关。第一次见面交换到电话号码就能验,比安全码更适合陌生人快速建立联系,因为不必另约时间。单次验证只是当下的快照,高风险窗口开始前记得再验一次。

时间有限,我该先验证谁

用影响范围排序。问自己「对方的账号若被接管,错误信息会扩散多远、敏感内容会外流多少」。指挥与协调窗口优先于一般成员,会转发现场汇报的节点优先于只接收的人,跨组织的单一联系窗口优先于同组织内已有其他确认渠道的人。排在所有人之前的仍然是你自己的账号,理由见「要验证别人,需先有对方的电话号码」那一则。

手机被查扣过再拿回来,看得出发生了什么事吗

看不出来。只要没有人用你的号码重新注册,身份密钥没换,画面就会照常显示绿色对勾。拿回设备之后要主动检查已关联设备清单与重要联系人的安全码变动。清单干净也只代表没有新设备挂进账号,不代表设备本身没被动过手脚。

号码是对方申请的、账单也是对方在缴,我还受保护吗

功能保护不到那一层。自动密钥验证确认密钥有没有被换掉,管不到号码的行政控制权在谁手上。对方若是合法的号码持有人,走电信商的正常渠道就能处理你的号码。号码的归属要另外处理,必要时先联系 113 保护专线评估风险,站上的家暴受害者的数位准备有进一步的准备方向。

验证联系人的时候,Signal 自己会不会知道我在查谁

原文说查询不带身份验证,不会跟特定用户账号绑在一起,只保证查询不会被绑到你的账号。服务器持有可验证随机函数的密钥,你要查某个标识符就得把它送过去,被查的标识符本身服务器看得到,审计方读不到明文则是另一层设计。

关掉自动密钥验证会有什么影响

你会回到原本的手动安全码流程,消息加密本身不受影响。关闭的理由通常是不想把任何信任放在 Signal 以外的第三方审计方身上。设置路径在隐私、高级、自动密钥验证。

Signal 的服务器被入侵,我会收到通知吗

不会有一则写着「服务器被入侵」的通知。你会看到安全码变动的提示,或是自动验证失败。密钥透明度的设计目标是让篡改留下无法抹除的证据,做不到即时警报。发现的时间点落在你或对方下一次检查的时候。

跟 WhatsApp、iMessage 的同类功能差在哪

三家处理同一个问题,选择的信任结构不同。WhatsApp 走第三方审计,由 Cloudflare 在外部盯着日志。Apple 的 iMessage Contact Key Verification 让用户的设备之间自行验证一致性。Signal 兼采两种做法,外部审计加上客户端对自己标识符的定期监测。使用门槛上,Signal 只有在你握有对方电话号码时才验证得了对方,纯用户名的联系人暂时用不到,WhatsApp 的账号本身就是电话号码,不会遇到同样的状况。

我该多久检查一次

没有标准答案,可以用事件驱动取代固定周期。收到安全码变动通知、对方换手机或换号码、你自己重新安装 Signal,以及任何一次感觉不对劲的对话,都是回去看一眼的时机。你自己的标识符由 App 定期检查,不需要你介入。

延伸阅读

站内:

站外:


  1. 实际上 Signal 会生成好几种不同类型的密钥对与衍生密钥,在 Signal 协议中协同运作,并非只靠单一组公钥与私钥。 

  2. 在 Signal 平台上,对应的是既有的「安全码」功能,需要当面验证,或通过第二个可信平台比对安全码。 

  3. 在现实世界里,签名很容易伪造。但在本文比喻的密钥透明度系统中,Signal 的第三方审计方使用的是密码学签名,难以伪造。 

  4. 译注:原文此处写的是「审计方没有移除或偷偷改动先前的页面」,依上下文应为职员(也就是服务器)的行为,翻译时已改回职员。