本系列将会介绍RSA、离散对数、椭圆曲线三大公钥加密算法,RSA算法将会作为该系列的第一篇。
1. 算法产生背景
公钥加密或说非对称加密其作用已经不言而喻,在实际中已经得到大量应用,比如HTTPS证书,其中便包含了网站的公钥信息。非对称加密与对称加密最大的区别是,加密与解密使用不同的密钥,通过公钥加密的内容只有通过私钥才能解密,反之亦然。因此,发布者完全可以把公钥公布于众,使发送者便于查询。与此相反,对称加密需要参与双方妥善保管密钥。
非对称加密非常类似数学里面没有反函数的一类函数,RSA选取的函数便是数论里面的同余理论,依赖的是大整数因数分解的困难性,下面我们不仅希望给出RSA算法的构造过程,更希望能证明该过程的正确性。
RSA算法可以通过数论和羣论来描述,算法导论中使用羣论来描述,而我们着重使用数论。
2. 预备知识
- 整除
符号m|a,表示m整除a,或a是m的倍数,等价于a= k*m - 同余
记a≡b(mod m),表示a、b除以m之后的余数相等,即同余。这等价于m|(a-b)
同余性质1:
若a1≡b1(mod m),a2≡b2(mod m),则(a1+a2)≡(b1+b2)(mod m)
同余性质2:
若a1≡b1(mod m),a2≡b2(mod m),则a1*a2≡b1*b2(mod m)
同余性质3:
若a≡b(mod m1),a≡b(mod m2),则a≡b(mod [m1,m2]),[m1,m2]为m1,m2的最小公倍数 - 最大公因数
记d=(a,m)为正整数a、m的最大公因数为d。当d=1时称a、m互质 - 欧几里德公式(证明请参考初等数论)
对任意的d=(a,m),存在整数x、y使得下式成立:
ax+my = d,特别当d=1时,存在ax+my=1,即:
ax≡1(mod m),此时称x为a的逆,记为a-1。因此,只要a、m互质,a-1始终存在。 - 费马小定理
若p为素数,则对任意正整数a,ap-1 ≡ 1(mod p)
3. 算法过程
- 随机选取2个大素数p,q,p≠q,计算N=p*q
- 选取一个整数e,e<(p-1)*(q-1),并且e与(p-1)*(q-1)互质
- 选择整数d,使得de≡1(mod (p-1)*(q-1)),根据欧几里德公式,d一定存在且唯一
- 销毁p、q,把(N,e)公开作为公钥,(N,d)妥善保管作为私钥。
假如用户A想通过公钥(N,e)加密整数n(n<N)给用户B,用户B通过私钥(N,d)进行解密,按如下步骤操作:
- 用户A计算c = (ne mod N),作为加密结果发送给A,换种表达方式是: c≡ne(mod N),并且c<N
- B接收到加密信息c后,计算cd(mod N)
因为c≡ne(mod N),所以cd≡ned(mod N)
因为ed≡1(mode (p-1)*(q-1)),所以ed=1+k*(p-1)*(q-1)
所以,cd≡ned(mod N) => cd ≡ n1+k*(p-1)*(q-1) (mod N) = n * n(p-1)*k*(q-1) (mod N)
因为p为素数,根据费马小定理:n(p-1) ≡1(mod p)
因此,根据同余性质2,n * n(p-1)*k*(q-1) ≡n(mod p) => cd ≡n( mod p) —–(1)
同里可得,cd ≡n( mod q) —–(2)
因为q、q为素数,N即为p、q的最小公倍数,因此根据同余性质3及式(1)、(2),cd ≡n( mod N)
也就是说cd 对N取余,则得到加密源数据n - 用户B用私钥加密消息发送给A后,解密过程与上同。
上面过程像变戏法一样完成了非对称加解密的过程,但却留下了很多疑问:
- 为什么要选择(p-1)*(q-1)作为计算的基础?
直观地说,是为了使用费马小定理,从ap-1 ≡ 1(mod p)可以看出,费马小定理可以把一个基于指数的大数的模转换为一个小数,这也是要求p、q必须为素数的原因。其实,费马小定理是欧拉定理的特例,欧拉定理:
对任意的整数(a,m)=1,存在公式:
aφ(m)≡1(mod m)
其中φ(m)称为m的既约剩余系的大小,即那些与m互质的余数的个数,当m为素数p时,φ(p)=p-1(除0外其他余数都与p互质),则得到费马小定理。
同样,应用欧拉素数公式可以得到:φ(N)=φ(p*q)=(p-1)*(q-1),这就是选择(p-1)*(q-1)作为计算基础的根本原因。 - 为什么加密元数据n需要满足n<N?
因为任何数与N取模都会小于N,这样才能保证cd ≡n( mod N) 结果的唯一性。如果加密源大于N,则可以分割为多个小于N的数据进行加密。 - 如果用户B用私钥(N,d)加密数据发给用户A,岂不容易被任意一个拥有公钥(N,e)的窃听者破解?
在设计上之保证A到B的信道是加密的,B到A之间的信道信息是公开的,更多是用来签名,用以证明消息的确是B发出的。
但B也可以使用A的公钥来发送数据已做到加密双端通信,这样A、B同时为公钥发布源。
4. 加密基础
RSA算法的加密基础在于,虽然公开(N,e),但却无法从(N,e)推断出(N,d),要想能推断出(N,d),则必须知道p,q,问题就转化为能否把N分解为两个大素数p、q乘积的问题。如果N能被容易的分解为p、q,则RSA算法将很容易被破解。 这个问题看起来貌似很简单,但事实证明当N足够大时(比如1024位),大数的因子分解非常困难:
- 我们选取N为1024位,即N=21024,因子分解采用事除法,只要试除1-N1/2的奇数,即总共要试除(1/2)*2512=2511个数
- 假如超级计算机每秒运行1万亿次,大概相当于240次,则总共需要2471秒,大概需要2436年
20多年的使用经验表明,即使采用其他更为先进的素数测试法,比如随机素数测试,因数分解的困难程度也超出想象。但在云计算如火如荼的今天,这似乎又变得有希望起来:
- 1999年,RSA-155(512 bits)被成功分解
- 2002年,RSA-158也被成功因数分解
- 2009年12月12日,编号为 RSA-768 (768 bits, 232 digits)数也被成功分解
因此,为了保证RSA的安全性只有提高N的位数,一般认为提高到2048位才相对比较安全。
5. 性能
RSA性能是非常低的,原因在于寻找大素数、大数计算、数据分割需要耗费很多的CPU周期,所以一般的HTTPS连接只在第一次握手时使用非对称加密,通过握手交换对称加密密钥,在之后的通信走对称加密。
6. 补充理论
- 素数有无穷多个
可用数学归纳法:设p1,p2,…,pn为已知素数,则p1*p2*…*pn+1必为合数,且不能被p1,p2,…,pn整除,而合数必存在素数因子,从而说明存在一个新的不同于p1,p2,…,pn的新素数,即素数有无穷多个 - 素数越”向后“越稀疏,并且数量可以估计
记π(n)为小于n的素数的个数
记L=n/logn,则极限lim(π(n)/L=1(n->∞),因此可以用L估计素数的个数。经过计算,当n=109时,其误差不超过6%,精度还是非常高的。 - 素数的测试方法
根据费马小定理:若p为素数,则对任意正整数a,ap-1 ≡ 1(mod p)
反过来,如果存在p满足上面等式,则p为素数的概率会非常高,p越大概率越高(具体证明请参考算法导论)。 - 反复平方法
因为d比较大,如果直接计算cd可能会比较费时,采用反复平方法则会比较快,具体请参考:http://blog.csdn.net/chen77716/article/details/7093600 - 模乘法羣
上面从e<(p-1)(q-1),ed≡1(mode (p-1)*(q-1)),可知ed=1+k*(p-1)*(q-1),更进一步,d<(p-1)(q-1)
因为关于模N互质的余数构成的乘法运算构成一个羣,即,a,b都是与m互质的模m的余数,即a*b≡1(mod m),如果a<m,则必有b<m。
羣有几个特性:
(1)运算封闭
(2)存在逆元
故可以得出上述结论。
7. 参考资料
【1】算法导论 【2】初等数论(潘承洞、潘承彪) 【3】wiki:
http://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95