切换深浅色
第 15 章 公钥密码学与密钥交换
15.1 公钥加密、数字签名和密钥交换是三种任务
对称密码已经能有效保护大量记录,但首次连接时,C与P可能没有共同秘密。让它们先在明文网络上发送一把AES密钥,显然会把秘密一并交给观察者。公钥密码学引入一对具有数学关系、职责不同的材料:私钥必须保密,公钥可以分发。具体算法依靠某种已知难题,使公开公钥不会同时暴露私钥。
“公钥密码学”不是“把每个网络字节都用公钥加密”的同义词。它至少支持三类需要严格区分的任务:
| 任务 | 输入输出的角色 | 要解决的问题 |
|---|---|---|
| 公钥加密 | 发送者用接收方公钥形成密文;接收方用私钥解密 | 没有共享秘密时,把内容交给特定私钥持有者 |
| 数字签名 | 签名者用私钥对消息形成证明;验证者用公钥验证 | 让不知道私钥的人检查消息是否由该密钥授权产生 |
| 密钥交换 | 双方各用秘密与公开交换材料计算共同结果 | 在网络上不直接发送最终秘密,建立会话材料 |
每一类都有具体方案、编码要求和安全条件。不能把一个签名算法当作任意消息的加密算法,也不能把“私钥加密、公钥解密”当成数字签名的通用定义。例如,后文的X25519用于密钥交换,Ed25519用于签名,名字相近不表示接口可互换。RFC 7748、RFC 8032分别定义这两种机制。
公钥加密通常不能单独证明发送者身份,因为任何拿到接收方公钥的人都可以发送密文。签名也不自动保密,因为验证者往往直接拿到消息及签名;公开验证能力恰恰是它的用途。密钥交换如果没有身份认证,又会遇到第13章的中间人问题。三者可以组合,却不能把其中一项的保证挪到另一项上。
现代安全通道常把高成本、低频的公钥操作集中在建立会话的阶段,然后把共同结果交给密钥派生机制,生成不同方向、不同用途的对称密钥。大量负载继续使用上一章的AEAD。这个组合把身份、密钥建立与持续记录保护拆开,便于分别管理各自的生命周期。
数字签名经常用到密码散列。散列把任意长度消息映射成固定长度摘要,例如SHA-256输出32字节;它不是可逆加密,也不需要一个保密的解密密钥。安全用途要求的不只是看似随机的外观,还包括难以从给定摘要找到对应原文,以及难以找到适当的不同消息产生相同摘要等性质。固定输出空间必然存在碰撞,所谓抗碰撞是难以有效找到,而不是数学上不存在。
散列本身也不认证发送者,任何人都能对新内容重算。签名把消息或按方案规定处理的摘要与私钥关联;带密钥的消息认证码则把消息与共享秘密关联。后文的HMAC属于后者,不能因为同样输出固定长度就与公开散列或签名混同。
最后,公钥的字节串仍然需要可信归属。32字节值编码成十六进制、Base64或配置字符串,只是表示方式;它没有自己说明属于哪个域名、用户或服务器。接下来先解释共同秘密的数学来源,再说明怎样把它与预期身份及当前会话绑定。
15.2 ECDH:公开交换两个点,分别计算同一个结果
Diffie-Hellman密钥交换的核心不是把秘密加密后寄给对方,而是让两端用不同秘密、相互公开的材料,分别算出相同结果。椭圆曲线上的版本称为ECDH。这里先用抽象的曲线点与运算解释共同结果,下一节再看X25519实际使用的32字节格式。
密码学中的椭圆曲线不是椭圆图形,也不是要求计算机做连续曲线绘图。一个常见模型由方程y²=x³+αx+β描述,坐标在模素数p的有限域里取值;满足方程的点,再加上一个特殊的单位元素,按规定的点加法形成群。有限域上的除法表示乘以模p的逆元,不是浮点除法。实际标准还要选择满足安全条件的曲线及子群;这里的方程形态只是其中一种,Curve25519使用另一种模型。
对两个普通不同点P₁=(x₁,y₁)、P₂=(x₂,y₂),且x₁不等于x₂时,上述模型的点加法使用斜率m=(y₂−y₁)/(x₂−x₁),再计算x₃=m²−x₁−x₂、y₃=m(x₁−x₃)−y₁,所有计算都在模p的规则下进行。点倍加采用相应切线公式,互为负点时得到单位元素,不能把除零情况直接套入普通公式。RFC 6090 §3给出这类基本运算。
一个只用于算术直觉、完全不安全的小例子是模17的曲线y²=x³+2x+2。P₁=(5,1)、P₂=(6,3)都在曲线上,m=2,因此两点之和为(10,6):x₃=4−5−6≡10,y₃=2×(5−10)−1≡6。这里相加的是曲线群中的点,不是把坐标分别相加得到(11,4)。实际密码曲线使用远大得多的参数,不能把这个小例子拿去保护通信。
把点G与自己相加a次记作[a]G,称为标量乘法。a是整数,G是公开选择的基点。高效计算不需要真的执行a次串行加法,可以利用倍加及组合;相反,给定G和A=[a]G,从A求出适用的a,就是椭圆曲线离散对数问题。参数选择的目标之一,是让前向计算可行、已知反向求解不可行。仅说“运算不可逆”过于绝对,应理解为在相应计算假设和资源范围下难以逆求。
C选择秘密a,公布A=[a]G;P选择秘密b,公布B=[b]G。随后:
text
C知道:a、A、B,计算 [a]B = [ab]G
P知道:b、A、B,计算 [b]A = [ba]G
旁观者:G、A、B,没有直接得到a或b群运算关系使两端的结果相同。旁观者能否从A、B直接算出共同结果,属于计算Diffie-Hellman问题;它与恢复私有标量的问题密切相关,但不能在任意群上不加条件地宣称二者严格等价。本书采用成熟方案的既定假设,不以这段直观代数替代安全证明。RFC 6090 §4。
原始共同结果通常还需要编码、有效性处理与密钥派生,才形成可供AEAD使用的K及其他材料。不能任意截取一个坐标,把同一段同时用作上下行密钥和nonce。不同方案的点编码、异常输入处理也不同,必须遵守对应规范,而不是把这里的抽象点图直接当作网络字段表。
最后,计算出共同结果并不表示确认了对方身份。C收到的B若被替换成A攻击者自己的公开点,C就会与攻击者建立另一个结果。ECDH解决共享秘密的建立问题,认证决定它究竟与谁共享。两者会在15.4节汇合。
15.3 X25519的32字节到底表示什么
X25519使用的Curve25519具有方程v²=u³+486662u²+u,坐标运算模p=2²⁵⁵−19进行。它采用Montgomery曲线模型,不能把上一节用于另一种模型的斜率公式原样搬来。X25519接口接受32字节标量材料和32字节u坐标,输出32字节u坐标;网络上不是把完整的两个坐标各发32字节。RFC 7748 §4.1、§5。
坐标按小端编码,公开基点的u值为9,因此输入编码是一个09字节后接31个00。私有输入的32字节在解释为小端标量以前要规范化:清除首字节最低三位,清除末字节最高位,并设置末字节次高位。于是实际使用的整数是2²⁵⁴加上8的某个倍数。这种位处理服务于方案的群运算安排,不表示新增了秘密随机性,也不意味着公钥要做相同处理。
对收到的u坐标,RFC7748要求屏蔽末字节最高位,并接受规定的非规范值、按模p约减处理。这里的接收规则与一般“拒绝所有非最短整数”的协议设计不同,必须服从该具体算法。标量、坐标和输出都长32字节,但各自的解释步骤并不相同。
计算可以采用Montgomery ladder,即按照标量位逐步维护相邻倍点的一种安排,每一位执行结构规则的倍加与差分加法,并用适当的条件交换选择状态。中间用射影坐标表示比值,避免每步都做模逆,最后恢复所需u坐标。规范给出从高位到低位的255步过程;常数时间的交换与底层域运算仍由实现保证。算法结构适合避免秘密相关分支,不代表任意照写的程序都自动没有侧信道。
协议两端的关系为:C生成私有材料a,公布A=X25519(a,9);P生成b,公布B=X25519(b,9)。两端分别计算X25519(a,B)与X25519(b,A)。RFC 7748 §6.1给出的公开向量如下,每一行均为32字节,连续十六进制仅为省去空格:
text
a = 77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a
A = 8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a
b = 5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb
B = de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f
Z = 4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742其中a和b是故意公开的测试私有材料,实际通信不能复用。编写时已独立核对两个公钥和双向共同结果Z相符。正常交换只需要把A和B给对方,不发送a、b或最终Z。仅计两个公开交换值是64字节;真实握手还包括协商、长度、身份及证明,不能把64字节当作完整TLS握手大小。
某些低阶输入会让共同结果成为全零,使对端的秘密不再按预期贡献结果。RFC7748讨论了检查与中止,但把这一检查描述为可选;使用X25519的上层协议可以要求更严格。TLS1.3的RFC8446 §7.4.2明确要求检查全零共同秘密并在出现时中止。因此本书不会把“RFC7748允许的底层接口输入”与“TLS握手应接受的共同结果”混为一谈。
Z也不直接证明身份。一个没有认证资格的外部主机同样能生成有效X25519公钥,并与服务器算出某个结果。认证机制必须说明这个结果与哪份可信凭据、哪段当前握手关联。32字节格式中没有藏着自动的用户名、有效期或访问权限。
15.4 数字签名把公开交换材料绑定到身份
假设C已经通过可信方式获得P的长期签名公钥Q。P在本次连接中生成临时交换值B,并对包含A、B和必要上下文的消息M签名。C用Q验证签名;中间人如果把B换成自己的值,却不能取得P的有效签名,就无法继续冒充P。这里长期签名密钥承担身份职责,临时交换秘密承担会话职责,二者不必是同一算法,更不应仅因存储长度相同就混用。
M需要明确涵盖什么。只签B可能没有绑定C发来的A和协商选项;只签一份固定声明可能被旧会话复制;不区分客户端与服务器角色可能留下跨角色混用空间。一种教学上的消息结构可以包含协议标识、双方角色、双方随机挑战、协商选项、A和B,各字段用固定宽度或长度前缀形成无歧义编码。它说明应绑定的关系,不是TLS的CertificateVerify实际字节格式;后者将在第16章逐项列出。
签名为何能被公开验证,可以用实际的Ed25519关系理解。以下限定RFC 8032 §5.1中的纯Ed25519,不把其上下文和预散列变体混入。本节用s表示秘密标量,Q表示签名公钥,Bₛ表示签名曲线基点,避免与上一节ECDH交换值B重名。
Ed25519在另一种曲线模型上操作。它从32字节私有种子计算SHA-512摘要,将前半按规范处理成秘密标量s,后半作为秘密前缀;公钥Q是[s]Bₛ的32字节点编码。这种编码保存y坐标及x的一个符号位,不是X25519的u坐标。两者都长32字节,不代表可以直接互换。
对消息M,纯Ed25519利用秘密前缀和M计算一个摘要,再按群阶L约减成r;计算R=[r]Bₛ。随后对R的编码、公钥Q的编码和M共同计算摘要,得到模L的k,最后形成S=(r+ks) mod L。签名为R的32字节编码与S的32字节小端编码串联,总计64字节。
验证者有Q、M、R、S,可以重算k,并检查适当的群关系。忽略编码和子群处理细节时,直观关系是:
text
[S]Bₛ = [r + ks]Bₛ = R + [k]Q规范要求先正确解码并检查S范围等条件,其标准验证关系带有余因子8:比较[8][S]Bₛ与[8]R+[8][k]Q;标准也允许使用足够的更严格关系进行检查。这里展示的是验证为什么可以利用公钥完成,不是让读者自行按简式替代完整验证规则。伪造者要在不知道相关秘密的条件下,为选定消息构造能通过全部检查的签名,并非仅仅复制这个等式就能做到。
纯Ed25519的r按秘密前缀和消息确定,因此不要求每次签名额外抽取独立随机nonce;这不表示私有种子可以不随机,也不表示其他签名算法同样没有逐次随机性要求。AEAD nonce、ECDH临时秘密和签名内部标量虽然都可能以随机性话题出现,作用与重用规则必须分别说明。
签名也不必直接处理所有握手字节。有些协议先对经过明确定义的握手记录形成摘要,再签一个包含上下文与该摘要的消息。这样既绑定整个协商,又区分签名的用途。哪些字节纳入摘要、是否包括消息头、发生重试时怎样处理,都必须由上层协议规定;不能只写“签了握手”便省略范围。
公钥归属仍是前提。若攻击者把Q换成自己的公钥,它可以为替换后的交换信息生成完全有效的签名。证书用签发者签名把服务标识与公钥等信息关联,接收者还需要依据自己的信任起点和预期服务名检查;证书本身不是私钥,也不是本次握手的活性证明。复制P的公开证书不应使攻击者获得P的签名能力。
共享密钥认证则采用不同信任结构。若C和P早已可靠共享秘密,可用相应消息认证码证明本次交互与该秘密有关,无需对所有客户端分发可公开验证的签名公钥。但所有共享者都可能具备制作相同认证材料的能力。身份粒度和泄露影响取决于谁共享秘密,不能把它表述成独立第三方可验证的唯一作者证明。
15.5 临时密钥为什么关系到前向保密
同一个公钥算法可以被放进不同生命周期的设计。服务器可能长期保存一个X25519私有值b,让所有客户端都使用相同B;也可能为每次握手生成新的b,只把长期签名密钥用于认证这个临时交换。两者都可以使用X25519,历史会话在泄露后的命运却不同。
先看静态服务器交换密钥的情况。客户端每次生成新的a,公开A,再利用预先知道的B算出Z=X25519(a,B)。服务器用长期b和收到的A算出同一Z。攻击者当前只监听,保存了A和后续密文;一年以后取得b,就可以重新计算X25519(b,A),恢复Z,并按公开协议派生当年的记录密钥。客户端当年把a擦除,也不能消除攻击者现在能走的这一条计算路径。
临时ECDH通常记为ECDHE,末尾E表示ephemeral,即临时。若双方每次使用新的交换秘密a、b,长期密钥只负责认证,完成会话后清除不再需要的临时秘密、共同结果及旧会话密钥,那么未来只泄露长期认证秘密,不应足以恢复已完成会话的记录密钥。这就是本书讨论的前向保密,常写FS或PFS。RFC 8446附录E.1按长期秘密失陷后的会话性质讨论这一目标。
text
静态交换:旧公开A + 后来泄露的长期b → 旧Z → 旧记录密钥
临时交换:旧公开A、B + 后来泄露的签名私钥
不等于获得已清除的临时a或b“前向”容易引起时间方向误解。它主要讨论未来发生长期秘密泄露时,过去的会话是否仍受保护;不是承诺泄露以后所有新连接继续安全。如果攻击者已经取得服务器签名私钥,并仍能控制通信路径,它可能为新的交换签名,冒充服务器参与未来握手。历史保密与今后认证是不同问题。
PFS也不保护已被窃取的会话密钥。攻击者若在连接期间读取当前记录密钥,当然可能解开其适用范围内的流量;若取得临时a或b,并保存了另一方公开交换值,也可能重新得到Z。PFS所排除的是“只凭后来泄露的长期认证材料恢复已结束会话”这条路径,不是“任何材料泄露都没关系”。
生命周期必须落实到实现。若程序名义上生成临时密钥,却把所有a、b、Z或会话密钥长期写入调试日志、崩溃转储或会话缓存,未来获取这些材料仍可能恢复历史内容。若临时b实际被大量连接长期复用,受影响范围也随之扩大。“临时”不能只依据变量名称,要看生成频率、作用域和清除时机。
预共享密钥PSK是双方已经拥有的秘密,它可以参与认证与派生。只从PSK和公开握手材料建立记录密钥,与再混入一次新鲜ECDHE结果,是不同的安全结构。TLS1.3明确区分两种模式,后一种才提供相应的前向保密;其0-RTT早期数据又发生在新鲜服务器交换完成之前,保证另行分析。不能把“协议支持PFS”扩展成“该协议所有阶段、所有模式都具有PFS”。
临时交换通常增加计算、交换材料和状态,也可能影响客户端何时具备发送应用数据的条件。减少往返、支持早期请求与保护历史秘密之间的取舍,会在VLESS Encryption等章节再次出现。应以具体密钥依赖图判断,不按算法名称或“0-RTT”字样直接评定。
15.6 从一次交换追踪认证、派生和密钥确认
把前面几节放进同一次连接,可以得到一条清晰的数据依赖链。下面仍是用于理解职责的概念流程,并非建议自行设计安全协议;TLS1.3的确切顺序和字段将在下一章替换这些抽象方框。
C事先可信地知道P的签名公钥,或者能验证把预期服务与该公钥关联起来的证书。C生成临时a、公开A和本次随机挑战N꜀,发出自己支持的协商选项。P生成临时b、公开B和挑战Nₚ,选择双方允许的选项,并为本次握手内容提供签名。C检查选择没有越出自己的提议,验证身份材料与签名覆盖的握手一致。
正在绘制图表…
查看图表原文
sequenceDiagram
participant C as 客户端C
participant P as 服务器P
C->>P: 本次挑战N꜀、临时公开值A、协商提议
P-->>C: 挑战Nₚ、临时公开值B、选择及身份证明
Note over C: 检查预期身份与当前握手的绑定
Note over C,P: 各自计算Z,再按同一上下文派生独立材料
P-->>C: 与本次握手绑定的服务器密钥确认
C->>P: 与本次握手绑定的客户端密钥确认
Note over C,P: 依据协议状态允许受保护应用数据
握手记录的摘要常称为transcript hash。它从规定的消息字节序列计算,绑定双方看到的协商历史;到底包括哪一条消息到哪一条为止,是每个派生或证明各自要定义的输入。把它理解成“本次握手的简短指纹”有助于直觉,但它仍然是按精确编码计算的字节结果,消息头、顺序和重试处理不能凭感觉省略。
双方有Z还不等于已经得到一把适用于所有用途的通用密钥。密钥派生函数KDF把共同材料与上下文整理为需要的输出,例如C→P的记录密钥、P→C的记录密钥、两方向的nonce基础材料,以及确认握手用的秘密。为用途设置不同标签,可以限制同一输出被错误地跨角色使用。第16章将具体解释HKDF如何完成这些步骤。
密钥确认用于证明对方确实算出了与当前上下文对应的秘密。发送方用相应秘密对握手摘要计算消息认证码,接收方用自己的结果验证。这与签名的职责有联系但不相同:签名绑定长期身份和交换内容,确认则检查派生结果及本次握手的一致性。仅仅收到一份合法的公开证书,或者本地成功算出一个Z,都不是对方已经完成同一次派生的证据。
假设中间人把C的公开A替换为A′再交给P。P的签名和确认将关联到它所见的A′;C按自己发送的A建立握手记录,就会发现证明不匹配。若攻击者直接把P的B换成B′,同样需要取得覆盖修改后内容的有效身份证明。若它只原样转发全部交互,可能仍位于路径上并知道通信时序,却不会因此获得端点秘密。经过某台设备与被该设备成功冒充,是两种不同情形。
随机挑战的作用也要放在整个绑定里看。旧服务器响应若绑定旧N꜀,通常不能拿来回答一个新N꜀;若挑战根本不在验证范围中,单独存在一个随机字段就没有这项作用。随机挑战不是防重放的万能开关,具体认证覆盖范围、状态和应用行为仍须核对。
协商选项需要同样绑定。若攻击者删掉客户端的强方案,让服务器只看到较弱提议,而双方的证明又不覆盖原始提议与最终选择,就可能产生降级空间。成熟握手会让篡改最终在验证中暴露,有时还定义额外的降级标记。不能把一个未经验证的“服务器说只支持旧版本”直接当作安全降级的依据。
最后,以上只有服务器身份的认证条件。P收到客户端密钥确认,说明对方参与了这次交换;如果任何人都能生成A,这并不说明该客户端具有某个代理账号。客户端凭据、证书或其他授权机制仍需另行加入,并明确在确认服务器之前能否发送、由哪层保护。下一篇VLESS的UUID与外层TLS认证正需要在这张职责图中分别定位。
15.7 把泄露放到具体时间线上
考虑三条已经正确认证、并使用新鲜双向临时ECDH的会话S₁、S₂、S₃。S₁在昨天结束,S₂正在传输,S₃尚未建立。攻击者保存网络记录,并在今天某个时刻取得一种秘密。先限定实现已清除S₁不再需要的临时材料,各会话没有错误共享密钥,再分别讨论。
| 今天取得的材料 | 对昨天S₁的影响 | 对当前或未来的影响 |
|---|---|---|
| 服务器长期签名私钥 | 单凭它不应恢复S₁记录密钥 | 可危及后续以该身份认证的握手,尤其有主动路径控制时 |
| S₂一个方向的AEAD记录密钥 | 不能据此恢复独立的S₁ | 暴露该密钥适用范围;是否能得到其他阶段取决于派生关系 |
| S₂临时ECDH私有值 | 不能据此恢复独立的S₁ | 可用另一方公开交换值恢复S₂共同结果及其派生范围 |
| 所有会话密钥的调试日志 | 日志若含S₁密钥,历史内容直接受影响 | 涉及日志保留的其他会话 |
| 一个恢复会话使用的PSK | 不自动等于原连接的全部记录密钥 | 恢复模式、早期数据与新鲜交换决定具体范围 |
表中最重要的是“材料对应的依赖范围”。记录密钥可能是由更高层秘密派生的末端输出。得到末端输出不应自动等于可以逆推出上层秘密;相反,得到上层派生秘密可能足以计算一系列后续输出。后文TLS中的traffic secret与实际AEAD key就是两个不同层次,不能在泄露分析里都写成含义模糊的“密钥”。
现在把条件改成静态服务器ECDH。若S₁、S₂、S₃都依赖同一个长期交换私钥b,那么今天取得b可能让攻击者结合已录下的每个客户端公开值恢复S₁和S₂,也危及继续使用b的新会话。这里变化的不是AES强度,而是旧密文到秘密的依赖图。定期更换b可以缩小某些时间窗口,却不能把更换以前长期复用的b变成已经实现逐会话PFS。
再考虑只单向派生的密钥更新:用当前派生秘密计算下一代,随后删除旧代。若派生函数具有相应单向性质,后来得到新代通常不能倒算已清除旧代,这有助于保护先前记录。但今天已经知道旧代的攻击者,可能和端点一样计算所有后续代。单向更新提供的过去隔离,不等于失陷之后自动恢复安全。
要在秘密泄露后重新建立攻击者不知道的材料,必须分析是否加入了攻击者无法获知的新秘密,以及身份认证是否仍可信。如果攻击者持续控制端点,它可能继续读取新产生的秘密;如果长期认证私钥仍在攻击者手中,单纯在同一不可信身份下重新握手也不能排除主动冒充。故障恢复涉及端点清理、撤销或替换认证材料以及重新建立信任,不能只把一个“更新密钥”按钮当作完整结论。
RFC 8446附录E.1.5与E.2分别讨论失陷后的限制和记录更新后的性质。这里先按依赖关系建立阅读方法;TLS具体在哪个阶段删除哪些材料、从哪个秘密导出哪一代,将在下一章结合准确派生图解释。
15.8 认证一个角色,不等于认证所有角色
同一台代理可能同时持有几类完全不同的秘密:对外证明服务器身份的签名私钥、客户端认证用的共享凭据、单次交换的临时私有值,以及多个方向的记录密钥。它们可以出现在同一个进程里,却不因此属于同一个安全角色。分析一种泄露时应明确得到的是哪一项,不能仅写“节点密码泄漏”。
例如,攻击者取得C的代理登录凭据,可能获得使用服务的资格;它是否还能冒充P给其他客户端,要看P的认证是否独立。若客户端固定了P的独立公钥,并且协议正确绑定当前交换,窃取一个用户凭据本身不等于取得P的身份私钥。若所有人共用的同一个秘密同时承担双向认证,泄露范围则可能更广。不能脱离设计给所有“密码认证”方案同一结论。
还有一个细致问题:得到甲的长期秘密,是否使攻击者可以在甲面前冒充任意乙。这个问题称为密钥失陷冒充,常写KCI。它比“能否冒充甲”更强,方向也相反。成熟的认证交换会分别分析。TLS1.3证书双向认证的相关目标见RFC 8446附录E.1;这里不据此宣称任何自定义协议自动满足同样性质。
认证还有可见性边界。一个服务拒绝无凭据请求,说明它具备某种访问门槛;不表示外部观察者不能知道端口开放、握手风格或失败分支。主动试探者可以合法地建立普通网络连接,观察服务对不同输入怎样反应。密码学上难伪造认证,与统计上难识别服务,是不同目标;REALITY等机制尝试改变后者时,也必须单独解释其外部行为和条件。
把一层认证放到另一层之上,需要继续检查绑定。例如,客户端在服务器身份确认前就发送可复用的明文凭据,可能把凭据交给假服务器;若先建立经过认证的保密通道,再在其中发送凭据,这条泄露路径会改变。另一方面,外层服务器认证成功并不让所有进入通道的用户都获得代理资格,服务器还要检查内层凭据及权限。
同样,网站HTTPS认证的是网站,代理通道认证的是代理。浏览器显示网站证书正确,不意味着代理的UUID、REALITY公钥或其他身份设置必然正确;代理通道认证成功,也不允许忽略网站的证书错误。两层可能保护不同对象,失败判断必须回到具体端点。
后续章节将沿用三个问题:长期可信材料是什么,本次交换怎样绑定它,应用数据最终依赖哪些短期秘密。对TLS,这些问题将对应证书或PSK、握手记录和分阶段派生;对REALITY与VLESS Encryption,则要以固定版本源码追踪实际路径。相同的X25519或AEAD名字,只能说明复用了某项基础工具,不能代替整套协议的分析。