你可以把 VPN 公钥交给对端、服务商或论坛,隧道仍然成立。但私钥不能交出去,即便是给客服,因为交出私钥就等于交出它证明的身份。这个判断很少这么干脆,因为人们会搞混自己看的是密钥对的哪一半,也因为有些部署把公钥当成名字用。三项检查可以定论:你手上是哪一半、部署把它绑定到什么、以及更换要付出什么代价。

检查一:你剪贴板里是密钥对的哪一半

非对称密钥成对出现,而推导方向正是关键。在 WireGuard 里,私钥是 32 个随机字节,公钥由它算出;反过来行不通。wg genkey写的是私钥值,wg pubkey推导出公钥,只有后者才该出现在发给对端的消息里。

wg genkey | tee private.key | wg pubkey > public.key
chmod 600 private.key
openssl x509 -noout -pubkey -in server.crt

证书世界用的是同一套分工,只是零件更多。服务器证书带着公钥和名字,并由一把从不离开 CA 的 CA 私钥签名。验证该服务器的客户端需要的是公开的 CA 证书,完全用不到 CA 的私钥签名密钥。

如果不确定手里是哪种值,看标记而不是文件名。以 -----BEGIN PRIVATE KEY----- 开头,或者更老的 BEGIN RSA PRIVATE KEY 形式,就是秘密的那一半。没有这个标记、能直接粘贴的值,才是可以分享的候选,但还要过下面两项检查。

检查二:部署把这个公钥绑定到什么

密码学安全性和匿名性是两回事。WireGuard 对端的公钥是部署内部一个稳定的标识:服务器配置里列着它,握手时用它命名,管理员读日志时每次该对端连接看到的都是同一串字符。把公钥贴在关于自己配置的提问旁边,就等于把这串字符和帖子里其他所有信息绑在了一起。

证书天生就会泄露身份。subject 和 subject alternative name 都可读,而对公开可信的 TLS 证书来说,证书本身会发布到可检索的 Certificate Transparency 日志里。这些都不暴露私钥,却都暴露了一段关系。

部署的差别就在这里,也正是它决定答案。实验室服务器上的一次性测试对端,和标识公司站点间端点的那把密钥,是完全不同的东西,哪怕字节看起来一模一样。

检查三:你能撤销什么,多快能撤销

第三项检查把两半彻底分开。已经公开的公钥,可以按你的节奏更换。已经公开的私钥则收不回来:删掉自己那份,碰不到别人已经拿走的副本,而每个曾信任它的对端,现在都在信任一个外人所持有的东西。

撤销是配置动作,不是密码学动作。WireGuard 不提供撤销列表,所以你要做的是移除对端:

wg set wg0 peer <peer-public-key> remove
# then delete the [Peer] block from the config so it does not return on restart

OpenVPN 基于证书的部署会吊销证书,并发布一份 CRL,服务器通过 crl-verify 真正去查。没有这条指令,撤销列表只是摆设。无论哪种,顺序都一样:签发替代品、通过受支持的渠道分发,然后让旧身份退役。

把三项检查揉成一项会犯的错

现实中的泄露大多不是某人决定公开私钥,而是把整份配置贴到论坛上,例如一份 WireGuard 的 .conf 里有 PrivateKey 行,或者一份 .ovpn 里嵌着密钥块,或者一张客户端窗口截图恰好拍到了密钥栏。公钥本身大概没问题,它只是和有问题的那部分一起出门了。

客服流程是第二个来源。正当的验证步骤都不需要你的私钥,因为对方需要的东西可以从公钥那一半推出来。当表单或某个人索要私钥值时,正确的回答是公钥,外加在本地生成它的命令。

日志和截图属于同一类。诊断输出可能带着密钥材料、会话标识和内部地址,为了回答一个问题把所有这些都贴出去,是拿一点方便换更大的暴露。

私钥泄露之后,让身份退役

如果私钥确实出去了,就把这个身份当作已退役。生成新的一对,把公钥装到对端期待的位置,移除旧对端或吊销旧证书,并检查你发布过的那些地方。你删不掉自己控制不了的副本,所以移除是为了将来,而不是为了过去。

然后把这套分发写下来:哪把密钥属于哪台设备、谁手里有副本、替换品怎么送达、谁负责移除退役的对端。这些正是人们会忘的部分,而它们决定一次泄露还能被用多久。

相关文章