怎么把一个秘密拆给 N 个人

公司要三位高管同时到场,才能动用主密钥。家庭要多个家人各拿一片信物,才能恢复账户。团队要一份备份——少一人还能用,但任何一人单独都拿不全。

三个看起来很不一样的场景,本质是同一个问题:把一个秘密拆成 n 份,规定 k 份能恢复,少于 k 份完全没用。1979 年,Adi Shamir(RSA 那个 S)在一篇短论文里给了一个简洁到能压在一页纸上的方案。开源端到端加密相册 Ente 写了一篇博客把它讲得相当干净——他们自己用 Shamir 做主密钥恢复,写出来的解释带着工程实感,几乎不需要数学背景就能看懂。

两个点确定一条直线

文章从一件你已经知道的事开始:两个不同的点确定唯一一条直线。一个点不行——经过一个点能画无穷多条直线,每条直线穿过 y 轴的位置都不一样。

两个点确定一条直线

把秘密藏在某条直线穿过 y 轴的位置——比方说秘密是数字 7。画一条随机斜率的直线穿过 y=7 这个位置。斜率是什么不重要,它只是用来藏秘密的随机数。

然后给每个人一个直线上的点(不是 y 轴交点本身)。

把分片分给每个人

一个人拿到一个点,能画过它的直线有无穷多条,每条直线对应的 y 轴交点都不同——也就是说,这个分片跟所有可能的秘密都兼容。它什么也没透露。

两个人凑齐,直线唯一确定,秘密就是这条直线穿过 y=0 时的值。

这就是 2-of-n 方案。你想发多少分片就发多少(每个人拿一个不同的点),但任何两个就够恢复。

门槛更高 → 曲线更弯

如果你想要 3-of-n(任意三人能恢复,两人不行)?把直线换成抛物线——抛物线需要三个点才能确定。

3-of-5 用抛物线

秘密还是藏在 polynomial(0)。一般地:门槛 k 用 k-1 次多项式

  k=2:  y = a₁·x + secret                直线
  k=3:  y = a₂·x² + a₁·x + secret        抛物线
  k=4:  y = a₃·x³ + a₂·x² + a₁·x + secret  三次曲线

a₁a₂a₃ 都是随机数,每次生成分片时新选一组。秘密是 polynomial(0),每个分片是这个多项式上的一个点 (x, y)。重组时用 Lagrange 插值恢复多项式,读取 (0, ?) 那个值。

实际实现用有限域算术替代图纸上的实数。plopilop 在评论里把工程细节讲透:

你通常在有限域里做秘密分享,因为计算机不喜欢实数。一个分片是一个 (x, y) 点:x 可以很小(n 个人时通常用 log n 位),y 是域里的一个随机点。

"什么都没泄露"是字面意思

文章里这句话是整套方案的核心:

The useful part is not that the secret is hard to compute from too few shares. It is that too few shares contain no information about the secret.

不是"难破解",是根本不存在可破解的信息。这个区别比想象中重要——它把 Shamir 秘密分享(Shamir's Secret Sharing,简称 SSS)跟现代加密放在两个完全不同的安全维度上。

ahazred8ta 用一句话翻译给非密码学家听:

Plain vanilla Shamir is information-theoretic secure and is completely impervious to QC. I can take a 1-byte secret, make 'threshold of 10' Shamir shares from it, give you 9 of the 1-byte shares, and no computer in the universe can determine the secret.

普通 Shamir 是信息论安全(information-theoretic secure),对量子计算机完全免疫。给你 9 份 1 字节的分片(threshold 是 10),宇宙里任何计算机都算不出那个秘密——因为剩下的可能性是均匀分布的,不存在"算"这个动作。

这跟 RSA 不一样。RSA 的安全建立在"分解大整数很难"这个计算困难假设上——Shor 算法在量子计算机上能干掉它。SSS 不依赖这种假设,它依赖的是数学定义本身。

简单到能给中学生讲

这套方案到底有多简洁?评论里有位中学数学老师 naths88 给出最有说服力的证据:

我在教仿射函数(affine function)的时候就用这个。学生选一个 PIN 当斜率,生成两个点,把点分给两个其他同学,他们必须配对才能找回 PIN。学生总是很投入。

九年级的学生能上手的密码学方案。_jackdk_ 那条恰好对得上:"这个方案这么酷,完全可以在中学教,作为'计算机科学家用多项式能干的整洁事'的例子。"

freakynit 顺手做了一个浏览器里的可视化 playground——输入秘密、看多项式、组合分片,上手玩玩:

🔗 shamirs-secret-sharing.pagey.site

1979 年的方案,2026 年还在跑哪些关键基础设施?

DNS 根密钥davkan 在评论里讲了 Cloudflare 公开过的根密钥签名仪式:

大约需要 5 个人才能访问 DNS 根密钥,加上一些行政/见证人员。3 名 Crypto Officer 拿智能卡解锁硬件安全模块(HSM),2 名其他官员解锁装着 HSM 的保险柜以及装着智能卡的保险箱。一共有 7 名 Crypto Officer,任意 3 名就行。

整个互联网根域名系统的密钥仪式(KSK ceremony,根密钥签名密钥仪式)就是 SSS 的工程化版本——智能卡 + 保险柜 + 7 选 3 门槛。

HashiCorp Vaultproxysna:seal/unseal 流程到现在还在用。

Bitcoin 私钥DesiLurker:社区里有人用 3-of-5 SSS 存私钥——5 份分片,任意 3 份能恢复。

最日常的是 Hypomixolydian 那条:

Shamir 救过我一次。一份几乎忘光的备份突然要恢复,密码是随机的。还好我把分片分给了家人——以防万一。

跟 Reed-Solomon 的关系

这是评论区最有技术含量的支线。Reed-Solomon 编码——你下 par2 文件、CD 纠错、QR 码恢复用的那个——跟 Shamir 共享同样的多项式插值数学。但不能拿 Reed-Solomon 当秘密分片用

teravor 解释为什么:直接套 RS 会泄露信息,你需要先做一个 AONT(All-Or-Nothing Transform,全有或全无变换)把整个负载转成"任何子集都没意义"的状态。colmmacc 补一刀:

Reed-Solomon is an Erasure code, and I definitely wouldn't look to that for Secret Splitting. Those leakage models are gnarly.

Reed-Solomon 是纠删码(erasure code),绝不能用它做秘密分片——拿到部分分片会泄露什么、泄露多少,分析起来非常麻烦。这条很重要:两个数学等价的方案,工程意义完全不同——Reed-Solomon 解决的是"丢了一些块怎么恢复",Shamir 解决的是"凑不齐时让信息根本不存在"。同一组多项式插值公式,在不同语境下解决两个完全不同的问题,一个面对噪声,一个面对窥探。

想动手玩

评论里给了几个独立实现:

saidnooneever 那条评论可以收尾:

This is very nice explanation which needs no maths.

一个不需要数学就能讲明白的密码学方案,在 2026 年后量子(post-quantum)焦虑里看起来朴素得有点奢侈——它老(47 岁)、它简洁(一页纸够了)、它不依赖任何计算困难假设。Shor 算法毁掉 RSA,Grover 算法削减对称密码强度——但 SSS 待在自己的角落,不动如山。

🔗 HN 原帖 · 文章原文