RSA的证明


最初写这篇《RSA的证明》是看到了一篇好文——《“不给力啊,老溼!”:RSA加密与破解 》,但是这篇文章在网络上大部分的分享中,公式大多不完整。而且各处的推演使用的数学语言与程序员习惯的表示方法差异太大了。于是出了此文,对《RSA加密与破解》进行了总结,并将数学部分换成程序员易于理解的方式。但是大部分内容还是来源于《RSA加密与破解》,少量的借鉴使用了《RSA算法基础详解》进行补充说明。

但是,回过头来看这篇文章,虽然当初反复修改,但仍有很多地方表述不明确、不严谨、也不够简洁。例如公式(3)可以得到更多化简,这就导致推导证明RSA时可以更加简单高效;在证明RSA时本末倒置,没有把证明的根本目标说清楚;另外,对于n的选取,本应该有更详细的说明,n的选取本是RSA得以成立的至关重要的一点,但是国内网络上的资料似乎很少提及,或者不会进行详细说明。

因此,对此文再次进行了修改,希望能够与国内大部分胡乱转载的RSA资料有明显的区别,能够起到给网友从另一个角度看问题的启示作用。并尽量将问题说得详细,逻辑顺畅、严谨。

前言
RSA是一种非对称加密算法,能够将大家都能看懂的明文加密成旁人无法读懂的密文。相比之下,最早的加密,如凯撒移位加密,其加密和解密用的是相同的钥匙(密钥),被称作对称加密算法。这种算法,一旦知道了一个密钥,便可以获取所有加密通讯的明文。

但是,如果加密用一把钥匙,而解密只能用另一把钥匙,那么,即便窃听消息的人获得了加密密钥,也无法还原出明文。这样便极大的提高了加密通讯的安全性。这种加密与解密密钥不同的方式被称作非对称加密。

1977年,罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)三人共同提出了著名的非对称加密算法——RSA,是目前安全性最高的加密算法之一。

要想清晰的了解这个算法,首先要掌握几个数学概念、定理或公理,其中最核心的要算欧拉定理。17世纪的费马首先给出该定理的一个特殊形式,即费马小定理:
p是一个正的质数,a是任意一个不能被p整除的整数。那么,a^(p−1)−1能被p整除。

也就是
(a^(p−1))%p=1

费马有个习惯,就是在书边写注释,由于书边空白一般太小,导致他提出了著名的“费马猜想”却没有地方写证明,于是在书边空白处留下一句“我发现了一个美妙的证明,但由于空白太小而没有写下来”。导致相当长的一段时间内,这个猜想让无数后来人想破脑瓜也不得证。可见,在书边写注释也不是一个好习惯。同样的,”费马小定理“的证明,也是很久以后的事儿了。

一百年后,出了个大牛叫欧拉,话说欧拉一生写了70多本数学专著,几乎把当时所有数学领域都征服了一遍,这么一个具有征服癖的人,自然没有放过费马,于是欧拉狂虐费马小定理,将其扩展到一个更广的适用范围,用数学语言描述如下:
如果n是一个正整数,a是任意一个非0整数,且n和a互质,那么:
(a^ϕ(n))%n=1 (1)

其中,ϕ(n)是欧拉函数,ϕ(n)=从1到n-1中所有与n互质整数的个数。互质,说白了就是公约数只有1。那么,比如说5,则1,2,3,4都与5互质,因此ϕ(5)=4。

对于质数p,它和1,2,3,…,p-1都互质,所以ϕ(p)=p-1。比如ϕ(11)=10。

由于质数p有ϕ(p)=p−1。因此,从欧拉定理可以推出费马小定理。在欧拉虐了费马之后,我们可以忘记费马小定理了(话说这里只是调侃哈,费马还是超级牛的)。用一个例子简单的检验欧拉定理。如果n是6,那么ϕ(6)=2。让a是11,和6互质。112−1为120,确实可以被6整除,符合欧拉定理。

关于欧拉函数,还有一个推论:
m和n是互质的正整数。那么
ϕ(mn)=ϕ(m)ϕ(n) (2)

除了上面的(1)和(2),还需要提前说明一个点:
(a*b)%n=(a%n)(b%n)=((a%n)b)%n (3)

简单的证明如下:
假设a和b除以n的余数为c1,c2,则a和b可以写成a=n*t1+c1,b=n*t2+c2
那么,ab=n^2*t1*t2+n*t1*c2+n*t2*c1+c1*c2
因此,a*b除以n的余数为(c1*c2)%n,由于c1和c2都不能被n整除,因此(c1*c2)%n=c1*c2,即(a*b)%n=(a%n)*(b%n)。
根据此可以推论
(a^m)%n=((a%n)^m)%n=(a%n)^m

以上其实是令人枯燥乏味的数论方面的东西,这些东西本来在古代没太多实际意义,没想到现代计算机和通讯技术的发展,为这些理论开辟出广大的应用空间。RSA加密,便应用了以上理论。

在证明RSA算法前,我们先来了解下这个算法和加密解密过程
1.先选择两个质数p和q,让n=p*q;
2.而k=ϕ(n)=(p−1)(q−1)*;
3.选择任意d,条件是1<d<φ(n),且d与k互质;
4.取整数e,使得(d*e)%k=1。也就是说d*e=k*t+1,t为某一整数。根据欧拉定理(d^φ(k))%k=(d*d^(φ(k)−1))%k=1,可计算出e=d^(φ(k)−1)

(e, n)和(d, n)为密钥。

设有需要被加密的明文c,c与n互质。x为密文。
加密c的过程为:
x=(c^e)%n

解密x的过程为:
c=(x^d)%n

好了,轮到我们开工,证明这个算法了
要证明RSA,就是证明c经过加密再解密后仍然是c,也就是c=(((c^e)%n)^d)%n

证明下面主要使用了d*e=kt+1以及(3)及推论):
(((c^e)%n)^d)%n
=(c^(d*e))%n
=(c^(k*t+1))%n
=(c*((c^k)^t))%n
=(c%n)*((c^k)^t)%n
=(c%n)*((c^k)%n)^t

根据欧拉定理(1),对于任意c,如果c与n互质,那么:
(c^k)%n=(c^ϕ(n))%n=1

因此,
(c%n)*((c^k)%n)^t
=(c%n)*(1^t)
=c%n

因为c与n互质,所以c%n=c,也就是说:
(((c^e)%n)^d)%n=c

因此RSA得证。

关键点
根据上面证明可见,RSA算法的关键,在于找到一个与明文c互质的数n,如果c是一个整数,那么很容易找到与之互质的数,如果c是一组数字,如c1,c2,…,cx,那么如何找到一个n与所有的c都互质呢?
方法在于质数p和q必须比所有的c大,所得的n就一定与所有的c都互质。原因在于:
1.如果两个数之中,较大的那个数是质数,则两者构成互质关系,指数p和q比所有的c都大,因此p和q与所有的c都互质;
2.由于n只能分解成p和q,而所有的c都与p和q互质,所以n与所有的c都互质。

RSA的安全性
为了对n求余的时候,不会把数字弄混了,RSA算法要求所有被加密的数c要小于n。

但n大更重要的原因是要保护p和q。想破解,必须找到d。回顾RSA工作过程(注意n是公开的),可以这样破解:
1.先找到隐藏的p和q
2.知道了p和q,可以算出k
3.d*e = k*t+1,即找到一个e,可以让d*e-1被k整除。d就找到了。

上面的整个破解过程中,最困难的是第一步——找到两个隐藏的p和q。如果p和q都选得非常大,比如说200位,会导致n也非常大,有400位。寻找一个400位数字的质数分解,对现在的计算机而言并不容易,这需要做除法运算大约sqrt(10^400)/2次。相当于10^199次除法运算!以超级计算机天河2号为例,其浮点运算能力是每秒10^16级别。那么,用天河2号找到p和q大约需要10^174年。这个活,要请上帝出手了。不过,假如10^174年后,天河2号得到明文如下(如果天河2号还在的话):
”10^174年减1天后,此信息作废。“

那么,估计上帝也要哭笑不得了。

【1】符号%和函数mod()均表示取模运算,可以理解为求余,如5%3=2
【2】符号^表示乘方运算,如5^2=25
【3】关于n的选取这里只给出的一个简单的方法。一个反例是p、q与c不互质,例如p=5,q=7,c=70,很明显n=35,与c不互质
【4】本文资料参考《“不给力啊,老溼!”:RSA加密与破解 》,对其进行了简化,并用更加符合程序员的语言给出详细的RSA算法证明,原文链接为:http://www.cnblogs.com/vamei/p/3480994.html#!comments,如果原文公式显示异常,则可以参考:http://blog.jobbole.com/96702/
【5】参考资料《RSA算法基础详解》,来自:http://www.cnblogs.com/hykun/p/RSA.html

点赞