how to share a secret
Adi Shamir
文章主要讲了如何将数据D分为n份,任意k份可以重组成D,任意k-1份不会泄露任何关于D的信息。这种技术能为密码系统构建鲁棒的密钥管理机制,即使灾难破坏一半信息或者安全性被破坏只剩一部分也仍能安全可靠的运行。
关键词:加密,密钥管理,插值法(interpolation)
- Introduction
在文章[4]中,liu讨论了以下问题:
11个科学家从事一个秘密项目,他们希望把文档所在一个箱子里,箱子只有在6个或更多科学家在场时才能打开。最少需要多少锁?每个科学家最少需要保管几把钥匙?
不难证明最小的解决方案是使用462把锁和每人252个钥匙。这个数目显然是不实用的,当科学家人数增加时会呈指数级增加。
在本文中,我们将问题归纳为秘密为某个数据D(例如,安全组合),或者非机械式解决方案(操作这些数据)。我们的目标是将D分成n份
D
1
,
D
2
,
…
D
n
D_1,D_2,\dots D_n
D1,D2,…Dn,满足:
(1)任意k或多余k份
D
i
D_i
Di可以很容易地计算出D
(2)任意k-1或少于k-1份
D
i
D_i
Di信息不能准确计算出D(所有可能的值相同)
这样的机制称为一个
(
k
,
n
)
(k,n)
(k,n)门限机制。
有效的门限机制在加密密钥管理上非常有用。为了保护数据我们可以将数据加密,但是为了保护密钥,我们需要一种不同的方式(更深一层的加密是改变问题而不是解决问题)。最安全的密钥管理机制是将密钥保管在一个严加防护的地方(一个计算机,一个人的大脑或一个安全的地方),这种机制非常不可靠,因为意外或灾难(如计算机故障,意外死亡,恶意破坏)可以使信息不可访问。一个简单的方案是在不同的地方存储多份密钥,但是这样又增加了安全漏洞的风险(计算机渗透,背叛或人为错误)。使用
(
k
,
n
)
(k,n)
(k,n)门限机制,n=2k-1,可以得到一个鲁棒性非常好的密钥管理机制:即使
⌊
n
/
2
⌋
=
k
−
1
\left \lfloor n/2 \right\rfloor =k-1
⌊n/2⌋=k−1 份被毁也仍可以恢复出原始密钥。即使安全漏洞暴露了
⌊
n
/
2
⌋
=
k
−
1
\left \lfloor n/2 \right\rfloor =k-1
⌊n/2⌋=k−1份剩余k份也不能重组密钥。
在其他应用中,tradeoff(权衡,利益)不在秘密性和可靠性,而在安全性和易用性。例如,一个公司对它的所有校验进行数字签名(见RSA[5]),如果给每个执行官一份秘密签名key的副本,系统会很方便单也很容易被误用。如果每次签名都需要所有执行官的合作,系统很安全但不方便。标准的解决方案要求每个校验至少三个签名,通过一个(3,n)门限机制很容易实现。给每个执行官一个写有Di碎片信息的磁卡,任意三个就可以通过签名生成器生成签名key D的一个临时副本。签名生成器不含任何秘密信息因此不需要进行保护。在这个系统中,一个不忠诚的执行官至少要有两个同谋才能伪造公司的签名。
门限机制理想情况下适合这样的应用:一组有矛盾的、相互怀疑的个体必须合作。理想情况下,我们希望合作基于双方同意,但是这种机制赋予每个成员的投票权可能会使该组织的活动陷于瘫痪。 通过适当选择参数K和n,我们可以给予任何足够多的多数人采取一些行动的权力,同时给予任何足够多的少数人阻止它的权力。
- A Simple (k, n) Threshold Scheme 一个简单的(k, n)门限机制
我们的机制基于多项式插值:在二维平面中给定K个有不同的
x
i
′
s
x_i 's
xi′s点
(
x
1
,
y
1
)
,
…
(
x
k
,
y
k
)
(x_1,y_1),\dots(x_k,y_k)
(x1,y1),…(xk,yk),有且仅有k-1次多项式q(x)使得
q
(
x
i
)
=
y
i
q(x_i)=y_i
q(xi)=yi对所有i成立。在不失一般性的情况下,我们假设D是(或可以被看作)一个数字。为了把它分成
D
i
D_i
Di,随机选择一个k-1次多项式
q
(
x
)
=
a
0
+
a
1
x
+
⋯
+
a
k
−
1
x
k
−
1
q(x) = a_0+a_1x+\dots+a_{k-1}x^{k-1}
q(x)=a0+a1x+⋯+ak−1xk−1,其中
a
0
=
D
a_0=D
a0=D且:
D
1
=
q
(
1
)
,
…
,
D
i
=
q
(
i
)
,
…
,
D
n
=
q
(
n
)
D_1=q(1),\dots,D_i=q(i),\dots,D_n=q(n)
D1=q(1),…,Di=q(i),…,Dn=q(n)。
给定任意Di值的k个子集(联通他们的识别索引号),我们可以通过插值找到q(x)的系数,然后计算D=q(0)。否则,只知道k-1个值不能计算出D。
为了更准确的描述这个声明,我们使用模块化算法而非真实算法。整数集对素数p取模,形成一个可以进行插值的域。给定一个值为Data D的整数,选择一个比D和n都大的素数p,q(x)中的系数
a
1
,
…
,
a
k
−
1
a_1,\dots,a_{k-1}
a1,…,ak−1从整数[0, p)的均匀分布中随机选择,
D
−
1
,
…
,
D
n
D-1,\dots,D_n
D−1,…,Dn的值通过对p取模得到。
现在假设n份信息中有k-1份落入一个敌人手中 ,对于[0,p)中的每一个候选值D’他能且仅能由给定的k-1个参数构造一个k-1次多项式q’(x)使q’(0)=D’,q’(i)=Di。通过构造,这p个可能的多项式大致相同,因此敌人几乎不可能推算出D的真实值。
用于多项式评估和插值的高效
O
(
n
l
o
g
2
n
)
O(nlog^2n)
O(nlog2n)算法在文献[1]和[3]中进行了讨论,但是即使是简单的二次算法对实际密钥管理方案来说也足够快了。如果数字D很长,可以将它分解成更短bit的block(被独立处理的block)以避免多精度的数学操作。blocks不能任意短,因为p的最小可用值为n+1(在{0,p)中要求至少有n+1个不同的参数来求q(x))。但是,这不是一个严格的限制,因为16位的模数(可以用一个廉价的16位算术单元来处理)足以应对最多64,000片Di的应用。
这种(k,n)门限机制(与机械锁和密钥解决方案相比)有用的属性是:
(1)每部分信息的大小不回超过原始数据
(2)当k固定时,Di可以动态地增删(例如,当一位执行官加入或离开公司时)而不影响其他信息片(pieces)(一个piece被删除,仅当离职的执行官使它完全不可访问,包括他自己时)
(3)可以在不改变原始数据D的情况下容易的改变Di pieces,我们需要的只是一个新的有相同自由项的多项式q(x)。这种类型的频繁变化可以提高安全性,这样由安全漏洞暴露的pieces就不回累积,除非它们都是同一个版本的q(x)多项式的值。
(4)通过使用多项式值数组作为Di,我们可以得到一个分层机制,决定D所需的pieces数量依赖于它们的重要性。例如,如果我们给公司的主席3个q(x)的值,每个副主席两个值,每个执行官1个值,则(3,n)门限机制给检查签名需要:任意三个执行官或者任意两个执行官其中一个执行官是副主席,或者主席自己。
G.R.Blakley[2]发表了一个不同的(然而更低效的)门限机制