虎符
上周的一天午后散步,和同事聊起了古代的虎符,就下面这玩意儿:
这玩意儿作为调兵遣将的凭证在古代发挥了巨大的作用,现代美国依然是采用了类似的方式,可见,这种 将凭证分开存储 的思想在古今中外是殊途同归的。
那么,作为互联网安全的根基,现代密码学中是如何应用这种思想的呢?这里就用到了 密钥分存 的技术,该技术是如何实现 把一个密钥拆开来分别保存在各处 的呢?本文来解答。
进入话题之前,例行声明,本文不会涉及复杂的技术,我也不懂hardened key(用不到,也没时间学),本文仅仅是一篇技术散文,由虎符这个饭后百步走的聊天话题说开去。
密钥分存
不管是对称密钥,私钥还是口令,无论哪种密码,均面临一个两难的问题,通俗点说,即:
- 只存一份
以口令为例,比如记在脑里子是最安全的,然而遗忘了就没有任何办法了。 - 备份多份
仍以口令为例,为了防止遗忘,很多人会写在纸上,然而纸条被别人看到或者偷走怎么办?
显而易见的解决方案就是 风险分担 。这种想法来自中世纪欧洲的 公司 :一个个体户出海一损俱损,不妨多人共同出资成立一个 股份制公司 ,共同抵御潜在的风险。
在密钥分存技术上,需要找到一种类似的风险分担机制,即:
- m m m人中任意 n n n( m > n > 1 m>n>1 m>n>1)个人均可以恢复密钥
可见,任何单独的个人均无法恢复密钥,就算其中一个人被坏人拿着枪指着脑袋,他也无法泄露机密,除非坏人一下子把 n n n个人同时抓住才可以,这就大大降低了密码泄漏的风险。让我们看看这是怎么做到的。
编码到曲线
把密码片段编码到曲线上就看的很清楚了。以下通篇,我均以数字2作为要分存的密钥,即主密钥,虽然这看起来有点傻,但足以说明问题了。在以下的例子中,我们不保存数字2本身,而是 将它拆成多个数字,即分密钥 ,然后分开存储这多个数字,不同点在于,我们希望 将来使用多少个分密钥来恢复主密钥 。
- 希望2个分密钥来恢复
请看曲线: y = 0.5 x + 2 y=0.5x+2 y=0.5x+2
以上,我们 密钥编码到了直线上 ,点 A , B , C , D , E A,B,C,D,E A,B,C,D,E为分密钥,而点 F F F为主密钥。我们只需要记住点 A , B , C , D , E A,B,C,D,E A,B,C,D,E中的两个,两点成一线,就可以恢复主密钥 F F F,如果只知道其中一个点,那将无济于事。
嗯,这就是 现代虎符的数学原理 ,后面的就简单多了,简单看看。
- 希望3个分密钥来恢复
如果我们希望更加安全一些,比如3个持有分密钥的人均到场,才能恢复主密钥,那么就需要二次曲线了,因为我们知道,形如 y = a x 2 + b x + c y=ax^2+bx+c y=ax2+bx+c的曲线可以由3个点来确定(待定系数法)。
依然是先来一条曲线:
y
=
1.5
x
2
−
3
x
+
2
y=1.5x^2-3x+2
y=1.5x2−3x+2
知道分密钥点
A
,
B
,
C
,
D
A,B,C,D
A,B,C,D中的任意3个,就能恢复主密钥点
E
E
E。
- 希望4个分密钥来恢复
如果需要4个分密钥恢复主密钥呢?很简单了,3次曲线即可。
这里我们可以总结出规律了,如果需要
n
n
n个分密钥来恢复主密钥,则需要一条
n
−
1
n-1
n−1次曲线,而曲线可以用二项式表达:
y
=
a
1
x
n
−
1
+
a
2
x
n
−
2
+
a
3
x
n
−
3
+
.
.
.
a
n
−
1
x
+
A
y=a_1x^{n-1}+a_2x^{n-2}+a_3x^{n-3}+...a_{n-1}x+A
y=a1xn−1+a2xn−2+a3xn−3+...an−1x+A
其中
A
A
A为主密钥在曲线上的编码,
a
1
a_1
a1到
a
n
−
1
a_{n-1}
an−1是编码曲线的待定系数。
妙处
妙处在哪?
两点成一直线,三点成一条抛物线,四点…这些 n n n点次数和二项式系数一一对应,而这一切又能统一于泰勒级数!不得不佩服现代数学,感叹是现代数学支撑了现代文明。
摆上一瓶酒,像我这个傻逼一般欣赏现代数学。多少落寞惆怅,都随晨曦飘散,别人是不懂的。
不对称密钥分存
假设有一群 m m m个人分存了一个密钥,我们说只要凑够其中的 n n n个人拿出他们的分密钥,就能恢复主密钥,注意,这 n n n个人是 任意的 n n n个人 。
如果说有这么一个需求,即 n n n个人中必须有某个人,这该如何是好呢?换句话说, m m m个人任何一个人都无法单独恢复主密钥,要想恢复主密钥,必须请出其中的A先生,然后在剩下的人中再选出任意的 n − 1 n-1 n−1个人,这 n n n个人一起来恢复主密钥。
要怎么做到呢?
也简单。以以上例子中最基本的一次曲线为例,在编码分密钥点
A
,
B
,
C
,
D
,
E
A,B,C,D,E
A,B,C,D,E结束后,选择一个 分密钥master 点,比如是点
A
A
A,然后点
B
,
C
,
D
,
E
B,C,D,E
B,C,D,E分别和master交换一部分数据即可,以下是一个实现方式,但绝不仅仅局限于这一种:
这样在恢复主密钥的时候,则必须有 A A A出场,恢复主密钥需要两个步骤:
- 被选中的 n − 1 n-1 n−1个点首先和 A A A交换以横坐标排序对应的数据块;
-
n
−
1
n-1
n−1个点和
A
A
A一起完成主密钥恢复工作。
这两个步骤缺一不可,虽然 A A A为master,但是少了其余的 n − 1 n-1 n−1个点,它还是无法独立恢复主密钥。
好了,到底为止,原理就讲完了。下面这一节与此无关了,就着 编码到曲线 这个话题,聊聊椭圆曲线的离散对数难题。
离散对数难
思考了一下离散对数求解难这个问题。且看我的想法有无道理。
实域对数求解就很容易吗?其实也很难,只是没有离散对数那么难。
我们之所以觉得实域对数容易,是因为实数域是连续统,而基于连续统有一个超级超级超级超级强大的工具,那就是 微积分 ,因此,用泰勒级数展开求对数,太容易了,想多精确都可以,这取决于你能容忍多小的余项。现代计算机计算器计算对数时,几乎都是使用级数算的。
另外,实域的对数还可以用换底公式把复杂化为简陋,这个傻逼都会,就不说了。
离散域便完全不同了!
离散域就没有微积分工具了,或者说,至少目前为止,我们还没有发现离散域上类似微积分这样强大的工具,因此便不再有泰勒级数这等解法了,所以就只能挨个尝试,另外质数取模操作,连自然数的连续性都破坏掉了,这相当于取模洗牌操作!
我们认为它难,那是针对我们目前所能想到的计算手段而言。数学上可计算并不意味着应用中可计算。我们现在hold不住指数时间是因为我们的计算模型是线性的,如果出现了量子计算机,并且它真的表现的像量子力学基础所宣称的那样,那么所谓的离散指数难这个问题可能将不再存在。
浙江温州皮鞋湿,下雨进水不会胖。