与前章所述RSA公钥加密算法类似,离散对数加密算法也属于公钥加密算法,RSA依赖大数因数分解的困难性,而离散对数则依赖有限域上的离散指数的难计算性保障其安全。
目前三大公钥加密算法(RSA、离散对数、椭圆曲线)都依赖数论与群论的知识,在介绍具体的算法前有必要再简介下所关联的数学知识。
1.欧拉公式与φ(m)特性
在RSA公钥加密算法中已经提到欧拉公式、费马小定理,可以说是三大加密算法的基础,φ(m)描述的是m的既约剩余系(与m互素的余数构成的集合)的大小,对素数p来说,其既约剩余系为1,2,...,p-1,即除0外,集合中的任何元素均与p互素,因此φ(p)=p-1。这其实是欧拉剩余系大小的一个特例,一般地m=p1p2...pn(pi为素数),有φ(m)=(p1-1)(p2-1)...(pn-1)。
2. 模乘法群
对任意的正数m,其既约剩余系关于模乘构成一个群,如RSA公钥加密算法中所述,该群存在下面的性质:
- 封闭性:群中的任意元素a,b,c= a*b(mod m),则c也在群中
- 逆元:若对任意的a都存在b,使得:ab≡1(mod m),则称b为a的逆元,记为:a-1
3. 原根
对任意的整数(a,m)=1,则存在d满足:
ad≡1(mod m)(证明请参考初等数论)
若d0是满足上式的最小值,则d0|d,即d是d0倍数,若d0=φ(m),则称a为模m的原根,存在原根的模乘法群称为循环群。需要指出的是:对任意的模m来说,原根可能不存在,也可能存在多个。
下面自然引出一个问题:什么样的m才存在原根?数论中已经证明,m有原根的冲要条件为:
1,2,4,pe,2pe,其中:p为奇素数,e为任意正整数
也就是说m=2n(n>=3),必无原根。而m=17的原根为3,因为316≡1(mod 17)
4. 离散对数
设g为素数p的模循环群的原根,对任意的a,计算:
b=ga mod p----(1)
是容易的(通过幂取模算法)。反过来,给定b计算满足(1)式的a是非常困难的,a称为以g为基b的离散对数。
如果只是实数领域的指数运算,则可解出a = loggb,因为取模运算导致(1)式无法表达为该形式,但仍称a为离散对数。
因为a、b均为整数,不像实数那么“连续”,故称离散对数。
因为限定a,b都属于模p的循环群,而该群的大小为:φ(p)=p-1,故称“有限域”上的离散对数。
5.加密过程
离散对数加密存在三种形式,本质上这三种形式都是等价的:
5.1 加密形式1---标准Diffie-Hellman算法
假设A希望发送一条消息m(0<m<p)给B
- A选择一个随机数c(A的密钥),0<c<p-1,(c,p-1)=1。发送 x = mc mod p,发送给B
- B选择一个随机整数d(B的密钥),0<d<p-1,(d,p-1)=1。发送y = xd mod p =mcd mod p给A
- A产生z = yc-1,发送给B。其中cc-1≡1(mod p-1),因为(c,p-1)=1,所以逆元素c-1必存在。
z = yc-1 mod p = mcdc-1 mod p =md mod p(费马小定理)
- B计算zd-1=mdd-1= m。dd-1≡1(mod p-1)
过程的证明与RSA类似,参考RSA公钥加密算法即可。
这样通过AB之间的三次通信可以完成一次安全的数据传输,窃听者可以取得mc、mcd、md,但却无法计算出其离散对数c,d的值,从而保证加密算法的安全性。
5.2 加密形式2---T. ElGamal算法
A公开模p循环群及其原根g和ga作为公钥,a作为私钥。a随机选择,满足:1=<a<p。
假设B发送消息m给A
- B选择随机数k,1=<k<=p-2,不同的消息m必须选择不同的k
B发送(gk , mgak)给A,注意,实际发送的是(x = gk mod p, y = mgak mod p)
- A可以计算xa≡gak(mod p),则m = (gak )-1y(一次同余方程的解)
这里面有几个问题:
- 为什么不同的m要选择不同的k?
如果所有的m都使用相同的k,窃听者在已知消息m1(m1是窃听者产生的测试消息)的情况下,可能会截获他人的消息m2:
m1gak ≡y1 ---- (a)
m2gak ≡y2 -----(b)
因为m1已知,根据(a)很容易计算出gak =(m1)-1y1,从而根据(b)能很容易计算出消息m2=(gak)-1y2。但如果每个m选择不同的k,则可以避免这种情况。
- 为什么要选择原根g作为生成元(计算基础)?
对任意的a,ga都唯一对应群中的一个元素;同样,对任意的群元素b,都存在唯一的a(0<a<p),满足:b=ga,这就保证了(gak)-1的唯一性,也就保证恢复出消息m的唯一性。
与加密形式1相比较,加密形式2仅需要一次通信便可传递消息m,但却需要传递两个群元素(g
k , mg
ak)。通信次数少了,但每次通信的数据量增加不少。从本质上来讲,形式2是形式1的一个变种。
5.3 加密形式3---密钥交换
形式1和形式是通过直接加密消息m,在接收端直接还原消息m的方式,形式3于此稍有不同,是通过先交换共同密钥,在加密消息m的方式进行通信。
与形式2相同,A公开模p的循环群和原根g,假设用户A希望与B交换密钥:
- A选择一个随机数c,(0<c<p),发送gc mod p给B,作为公钥;将c妥善保管作为私钥
- B选择一个随机数d,(0<d<p),发送gd mod p给A,作为公钥;将d妥善保管作为私钥
- 此时A、B双方都能计算K=(gc mod p)d=(gd mod p)c=(gcd mod p),即K即为A、B之间的密钥
交换密钥的过程与消息m无关,有了密钥K后,A、B之间可以进行对称加密。形式3只是在密钥交换阶段进行了2此通信,之后便只有消息通信,非常适合程序实现。
6. 离散对数的困难性
上述三种加密形式都依赖离散对数的困难性,知道(g,g
c)但无法得到c,目前存在几种攻击离散对数的方法:
- Shanks算法
该方法类似大整数因子分解的试除法,若c有1024位将是一个天文数字,即使超级计算机也无法完成
- Pollard算法
针对p-1有素因子的特殊情况
- Pohlig-Hellman算法
- 指数演算法
关于每种攻击算法的特点,及为抵御攻击选取素数p的方法,不再做详细介绍。(有兴趣的可以参考<<密码学原理与实践>>)
但无论何种算法,只要精心选取素数p都可抵御目前的攻击,目前普遍认为攻击离散对数的困难性要高于RSA。
7. 离散对数与RSA的区别
RSA的公钥、私钥均有接收端(比如Server)签发,非常适合互联网上的证书服务:服务端签发证书,客户端使用该证书,保证客户端到服务端之间的通信安全。如果双端都需要非对称加密,则双方都必须发布公钥,并且公钥不能频繁变更,做不到每个端点一个公钥,因此,任何一个接收端都可以查看发送端的消息(公钥解密)。
离散对数形式相对比较灵活,每个发送端可以在发送每条消息是指定自己的公钥,但接收端回复的消息也只有发送端才能解密;也可通信握手阶段协商密钥,接下来根据协商的密钥走对称加密。
8.总结
复杂的公钥加密过程,其实仅依赖一个简单的数学公式,这也正是数学之美。很多人研究公钥加密算法,而另一些人却拼命研究如何破解这些加密算法,正所谓“道高一尺,魔高一丈”。正是这种“自己创造问题,自己解决”的“愚公”精神,推动了整着整个网络安全向前发展。
【参考资料】
- http://en.wikipedia.org/wiki/Discrete_logarithm
- http://blog.sina.com.cn/s/blog_5b5ed0720100atsy.html
- 初等数论(潘承洞)
- 密码学原理与实践