← 返回首页

用Shamir秘密共享写一份数字遗嘱

发布时间: 2026-04-22 11:26(北京时间)

摘要: 作者体验了cyphar/paperback项目,该项目基于Shamir秘密共享和多种密码学原语(ChaCha20-Poly1305、BLAKE2b、Ed25519)实现数字遗嘱功能。文章详细描述了备份与恢复流程,分析了密钥碎片加密、Multiformats编码、Z-Base-32文本回退等设计细节,并指出其人性弱点(合谋风险、存活依赖)。整体语气冷静,带有技术探索的满足感。

标签: 密码学, Shamir秘密共享, 数字遗嘱, Multiformats, Z-Base-32, 技术体验, 反思, 结构化分析

字数: 2132

原文链接: /7402396589/QBXnNCOkd

cyphar/paperback 也很好玩。
不过现在有些困,准备休息,明天再讲讲。

附图是我加密了一份txt文档,我把生成的Main Document和3份Key Shard 我都发出来了(理论上只需要2份就可以解密)。(已经跑过recover流程了) ​​​

/cyphar/paperback 这个项目还处在V0版本。我玩下来感觉“backup”流程是比较顺畅的,输出文件的排版风格我也十分喜欢,但自带的“recover”流程比较繁琐,但至少还是能顺利跑通。

本该昨天就写下这篇笔记发出来,但力量训练后的酸痛抑制了不少表达的欲望,一头扎进《概率论沉思录》中,半路写了段碎碎念,一天也就过去了。

带着“玩一下”的心态体验这个项目,可以避免直接触及底层的复杂密码学知识。这也是从正念中学到的“带着初心”去感受。paperback用起来十分简单,准备好一份需要加密备份的文档,执行backup指令就能拿到加密后的“主文档”和一系列的钥匙碎片的文档。钥匙碎片的数量涉及到两个变量,N就是要做多少把钥匙,K是至少要多少把钥匙才能开锁。

观察生成出来的“主文档”有两个主要部分。第一部分是加密后的数据,数据在V0版本最多只能写在9个二维码里面,虽然原理上主文档是可以多页的,但作者暂时不想拓展。第二部分是Checksum,这里有二维码,也有一段文本,作用是:text fallback if barcode scanning fails。

“钥匙碎片文档”相对复杂一些,有三个部分。第一部分是加密的钥匙碎片,我本以为自己看错或是理解错了,但钥匙碎片也被加密了。密文也是包含二维码和text fallback部分。第二部分是Checksum,一样是二维码和text。第三部分有一条虚线和裁剪符号,下方存的是钥匙碎片的密码,这段密码没有提供二维码,纯粹的Codewords,类似助记词。

recover流程比较繁琐(不是算法流程上的繁琐,只是扫码复制粘贴比较麻烦),扫描“主文档”的9个二维码复制粘贴,不需要按顺序,能凑齐完整即可。校验成功后开始插钥匙碎片,输入一份钥匙碎片的密文,然后输入对应的Codewords。继续录入钥匙碎片直到碎片数量达到K份,之前的文档就被recover出来了。

玩到这大概就理解项目的意思了。可以加密一份文档,生成加密的主文档和若干钥匙,然后把主文档和钥匙分发给别人,只要有K个人在场,就能解密还原出文档。听起来是不是有点遗嘱的意味。

前面说了钥匙碎片也是加密的,所以实际上还可以把所有钥匙碎片的Codewords都剪下来,单独交付给一个人。那这个人就成了“必须在场”否则无法解密的人。

——————

玩过以后,就该学了。这个项目的底层涵盖了很多现代密码学知识,全部嚼碎了写出来估计还有些费劲,我简单列下涉及到的内容,然后展开讲一些我认为比较有趣的东西。

对称加密与认证加密环节用到了 ChaCha20-Poly1305
哈希用的是 BLAKE2b-256
签名是 Ed25519
钥匙碎片的原理是 Shamir’s Secret Sharing (SSS) ←有限域是GF(2^32)伽罗瓦域

SSS有点像古时候的“虎符”,只有准确“合符”才能出兵。SSS可以将一个秘密S分割成N份,当秘密份额达到门限K的时候,秘密就可以被还原。而只要秘密份额小于K,能做到0信息泄露。

除了上面这些“比较硬核”的密码学概念,我觉得比较有趣的是项目还用到了Multiformats。在平时遇到hash值大都会注明这是什么散列算法,比如MD5:xxxxxx或是SHA256:xxxxxx。但如果忘记标注,过一段时间再看这些哈希值可能会摸不着头脑,甚至校验也要费点功夫。而Multiformats规范就是在数据前加个前缀,告诉大家这串东西是怎么来的,一共有多少字节的数据。那大家不管是过去了50年还是100年,只要看到头部就可以知道,这串是Ed25519的数字签名,那串是Z-Base-32编码。

再讲讲输出中二维码对应的text fallback,这是用到了Z-Base-32编码。这个编码的字符集如下:
y b n d r f g 8 e j k m c p q x o t 1 u w i s z a 3 4 5 h 7 6 9
这对人眼辨认十分友好,对着纸张敲进终端的时候就几乎不会出现错误(自己粗心除外)。所以项目中text fallback的意义是,旁边的二维码因为某种原因没办法扫描的时候,就可以通过输入Z-Base-32编码内容还原Checksum。

——————

这个项目整个架构略显复杂,但理清之后还是蛮开心的。加密、签名、分发、解密一环套一环,似乎有种冲动赶紧写一份遗嘱,加密后交给信任的人和律师。

但这个看似还比较完美的方案其实弱点也很明显。这里说的弱点不是某种算法有缺陷,而是在于“人”。

必须至少包含K份钥匙碎片才能解密这个条件带来的隐患太多了。这意味着不仅要相信钥匙碎片交付的人不会合谋,还要相信需要解密的时候他们还活着/能找到碎片。

image

image

image

image