Description: 前言 本文全面的介绍了RSA算法的概念、原理、证明和实现。我在写作本文之前在网上查阅过相关资料,可这些资料不是含糊其辞就是满篇谬误。所以我力求用通俗易懂的文字将算法深入剖析,用最严谨的步骤进行论相关的各项算法,以降低文章的阅读难度。读者只要学过初中代数就可以理解全文,我衷心希望更多读者能认识到加密算法其实并不难。文中的算法均为伪代码,由于伪代码没有办法进行测试,再加上我个人数学功底比较薄弱,所以错漏之处在所难免,还请各位老师给予指教。质疑或指正请发送电子邮件到fireseed1949@hotmail.com,我会认真阅读并回复的!感谢北航数学系(毕业)李桢老师、西工大计算机系(毕业)张小宁老师在数学上对我的指点。另注:文中mod就是求余的符号,X mod Y表示X除以Y所得的余数。 ·概述 RSA算法是世界上第一个既能用于数据加密也能用于数字签名的非对称性加密算法。它易于理解和操作,所以流行甚广。算法的名字以发明者的名字命名,他们是:Ron Rivest,Adi Shamir 和Leonard Adleman。虽然RSA的安全性一直未能得到理论上的证实,但它经历了各种攻击,至今未被完全攻破。为了让读者更容易的理解RSA加密,先大概讲述一下信息加密技术的相关概念和原理。我们对于在数字媒体上进行交换的数据进行加密的方法称为信息交换加密技术,它分为两类,即对称加密和非对称加密。在对称加密技术中,对信息的加密和解密都使用相同的钥,也就是说一把钥匙开一把锁。这种加密方法可简化加密处理过程,信息交换双方都不必彼此研究和交换专用的加密算法。如果在交换阶段私有密钥未曾泄露,那么机密性和报文完整性就可以得以保证。对称加密技术也存在一些不足,如果交换一方有N个交换对象,那么他就要维护N个私有密钥,对称加密存在的另一个问题是双方共享一把私有密钥,交换双方的任何信息都是通过这把密钥加密后传送给对方的。如三重DES是DES(数据加密标准)的一种变形,这种方法使用两个独立的56为密钥对信息进行3次加密,从而使有效密钥长度达到112位。在非对称加密(或称公开密钥加密)体系中,密钥被分解为一对,即公开密钥(公钥)和私有密钥(私钥)。这对密钥中任何一把都可以作为公开密钥,通过非保密方式向他人公开,而另一把作为私有密钥,加以妥善保存。公开密钥用于加密,私有密钥用于解密,私有密钥只能由生成密钥的交换方掌握,公开密钥可广泛公布,但它只对应于生成密钥的交换方。非对称加密方式可以使通信双方无须事先交换密钥就可以建立安全通信,广泛应用于身份认证、数字签名等信息交换领域。非对称加密体系一般是建立在某些已知的数学难题之上,是计算机复杂性理论发展的必然结果。最具有代表性是RSA公钥密码体制。在RSA算法中,我们先要获得两个不同的质数P和Q做为算法因子,再找出一个正整数E,使得E与 ( P - 1 ) * ( Q - 1 ) 的值互质,这个E就是私钥。找到一个整数D,使得( E * D ) mod ( ( P - 1 ) * ( Q - 1 ) ) = 1成立,D就是公钥1。设N为P和Q的乘积,N则为公钥2。加密时先将明文转换为一个或一组小于N的整数I,并计算ID mod N的值M,M就密文。解密时将密文ME mod N,也就是M的E次方再除以N所得的余数就是明文。因为私钥E与( P - 1 ) * ( Q - 1 )互质,而公钥D使( E * D ) mod ( ( P - 1 ) * ( Q - 1 ) ) = 1成立。破解者可以得到D和N,如果想要得到E,必须得出( P - 1 ) * ( Q - 1 ),因而必须先对N进行因数分解。如果N很大那么因数分解就会非常困难,所以要提高加密强度P和Q的数值大小起着决定性的因素。一般来讲当P和Q都大于2128时,按照目前的机算机处理速度破解基本已经不大可能了。 ·证明下面将会开始讨论RSA算法的原理及其算法证明。如果您只关心RSA算法的实现,则可以略过这一步。我把每一个有用的定理都用粗标标记了,对于数学不很在行的朋友可以只了解一下相关定理的说明而不需要验证求证过程了。一、 费马小定理[1]的转化费马小定理:有N为任意正整数,P为素数,且N不能被P整除,则有: NP mod P = N 费马小定理可变形为: NP - N mod P = 0 ( N ( NP - 1 - 1 ) ) mod P = 0 因为 ( N ( NP - 1 - 1 ) ) mod N = 0 所以N和P的公倍数为: N ( NP - 1 - 1 ) (1)又因为N与P互质,而互质数的最小公倍数为它们的乘积,所以一定存在正整数M使得:N ( NP - 1 - 1 ) = MNP成立。并化简为: NP - 1 - 1 = MP ( NP - 1 - 1 ) mod P = 0 可以变形为: NP - 1 mod P = 1 (2)(2)就是费马小定理的转化定理,为方便叙述,下文简称为定理一。小提示,可能很多人认为费马小定理本来就是(2),实际上不是这样,因为费马小定理的转化非常容易,而转化定理又是一个无论在数学上还是计算机程序上都很常用的公式,所以人们就普遍认为(2)就是费马小定理了。二、 积模分解公式有X、Y和Z三个正整数,且X * Y大于Z,则有: ( X * Y ) mod Z = ( ( X mod Z ) * ( Y mod Z ) ) mod Z 证明如下当X和Y都比Z大时,可以将X和Y表示为: X = ZI + A (1) Y = ZJ + B (2)将(1)和(2)代入( X * Y ) mod Z得: ( ( ZI + A )( ZJ + B ) ) mod Z ( Z( ZIJ + IA + IB ) + AB ) mod Z (3)因为Z( ZIJ + IA + IB )是Z的整数倍,所以(3)式可化简为: AB mod Z 因为A和B实际上是X和Y分别除以Z的余数,所以有: ( X * Y ) mod Z = ( ( X mod Z ) * ( Y mod Z ) ) mod Z成立。当X比Z大而Y比Z小时 X = ZI + A 代入( X * Y ) mod Z得: ( ZIY + AY ) mod Z AY mod Z 因为A = X mod Z, 又因为Y mod Z = Y,所以有: ( X * Y ) mod Z = ( ( X mod Z ) * ( Y mod Z ) ) mod Z成立。同理,当X比Z小而Y比Z大时,上式也成立。当X和Y都比Z小时,X = X mod Z,Y = Y mod Z所以有: ( X * Y ) mod Z = ( ( X mod Z ) * ( Y mod Z ) ) mod Z成立。积模分解公式成立。三、 定理二有P和Q两个互质数,如果有X mod P = 0,X mod Q = 0,则有:X mod PQ = 0 证明:因为P和Q互质,所以它们的公倍数为KPQ(K为整数),最小公倍数为PQ。又因为X为P和Q的公倍数,所以X / PQ = K,所以X mod PQ = 0。四、 定理三有P和Q两个互质数,设有整数X和Y满足Y mod P = X,Y mod Q = X,则有:Y mod PQ = X 证明: X = Y mod P 可以表示为: Y = X + kP Y - X = kP 即Y - X可以被P整除,同理Y - X可以被Q整除。又因为P、Q互质,根据定理二可得: ( Y - X ) mod PQ = 0 即 Y mod PQ = X 五、 定理三的逆定理有P和Q两个互质数,设有整数X和Y满足Y mod PQ = X ,则有:Y mod P = X,Y mod Q = X 证明: Y mod PQ = X 可以表示为: ( Y – X ) mod PQ = 0 显然 ( Y – X ) mod P = 0且 ( Y – X ) mod Q = 0 所以原命题成立。六、 RSA定理若P和Q是两个相异质数,另有正整数R和M,其中M的值与( P - 1 )( Q - 1 )的值互质,并使得( RM ) mod ( P - 1 )( Q - 1 ) = 1。有正整数A,且A
PQ,且A不是P的倍数也不是Q的倍数时,(2)可变形为: B = ( AAK ( P - 1 )( Q - 1 ) ) mod PQ 根据积模分解公式可变形为: B = ( ( A mod PQ )( AK ( P - 1 )( Q - 1 ) mod PQ ) ) mod PQ (3)根据定理三的逆定理: AK ( P - 1 )( Q - 1 ) mod PQ = ( AK ( P - 1 ) ) ( Q - 1 ) mod Q 根据费马小定理可得: ( AK ( P - 1 ) ) ( Q - 1 ) mod Q = 1,则 AK ( P - 1 )( Q - 1 ) mod PQ = 1 故( 3 )可转化为: B = ( A mod PQ ) mod PQ 因为A
PQ,且A不是P的倍数而是Q的倍数时,A可表示为A = NQ,N为一小于A的整数。那么(2)式可变形为: B = ( NQ )K ( P - 1 )( Q - 1 ) + 1 mod PQ B = ( NK ( P - 1 )( Q - 1 ) + 1 )( QK ( P - 1 )( Q - 1 ) + 1 ) mod PQ 把Q作为公因子提出来,得: B = ( ( NNK ( P - 1 )( Q - 1 ) ) ( QK ( P - 1 )( Q - 1 ) mod P ) ) Q 用积模分解公式进行分解,得: B = ( ( NNK ( P - 1 )( Q - 1 ) mod P )( QK ( P - 1 )( Q - 1 ) mod P ) mod P ) Q 跟据定理四,NK ( P - 1 )( Q - 1 )和QK ( P - 1 )( Q - 1 )的值都为1,所以有: B = ( ( ( N mod P ) mod P ) mod P ) Q B = NQ mod PQ mod PQ mod PQ B = A mod PQ mod PQ mod PQ 因为A
1 E := E / 2,余数存入M IF M = 1 K := R * K END IF R := R * R NEXT R := R * K 再回到我们刚才讨论的幂模运算。事实上在(1)式中,我们需要求出的就是( N mod D )R的值,那么只要令上面伪代码中参量N的值为N mod D,并对结果R求R mod D就可以了,下面是基于上面求乘方算法的幂模运算的伪代码。算法二:计算N的E次方再取D的模,令R为计算结果。 R := N mod D R := R ^ E ;调用算法一 R := R % D 如果再利用上文过程中提到积模分解公式对算法做进一步优化,直接把取余的运算代入到乘方中,就成为了著名的蒙格马利快速幂模运算法,伪代码如下。算法三:蒙格马利法计算N的E次方再取D的模,令R为计算结果。 R := 1 A := N B := E WHILE B != 0 IF B & 1 ;判断是否为奇数 B := B - 1 R := R * A X := X % D ELSE B := B / 2 A := A * A A := A % D END IF NEXT 蒙格马利快速幂模运算,是目前世界上效率最高的幂模运算,很多硬件芯片在处理类似算法时都采用的这种方法。 ·寻找大素数为了有效防止破解,必要须找到两个很大的素数作为算法因子。而寻找大素数,是数学家们一个永恒的话题。素数的定义是只能被自己和1整除的自然数,按照常规的理解,使用计算机对一个很大的数进行素数测试时,需要遍历所有小于它且大于1的自然数,并逐个判断是否能被该数整除。这个过程对于非常大的素数而言是非常缓慢的。但是根据费马小定理,我们可以设计一种算法来快速测试素数。当A和Q互质时,有:AQ - 1 mod Q = 1,那么,我们可以通过判断AQ - 1 mod Q的值是否等于1对Q进行素数测试。如果取了很多个A,Q仍未测试失败,那么则认为Q是素数。当然,测试次数越多越准确,但一般来讲50次就足够了。另外,预先用常归算法构造一个包括500个素数的数组,先对Q进行整除测试,将会大大提高通过率,方法如下:算法四:费马定理测试可能素数P C := 500 ;素数表大小 S[ 0 TO C ] ;素数表 B := P - 1 T := 50 ;表示进行测试的次数 A := 0 FOR I := 0 TO C ;进行素数表初步测试 IF P mod S[I] = 0 RETURN FAILE END IF IF P 1 RETURN FAILE END IF NEXT I RETURN PASS 这个算法看起来很完美,但实际上从一开始它就犯了一个很大的错,那就是对于任意与Q互质的A都有AQ - 1 mod Q = 1,这是素数的性质,是素数成立的一个必要条件,但不是充分条件!让我们来看一下29341这个数,它等于13 * 37 * 61,但任何与它互质的A都有A29341 - 1 mod 29341 = 1成立。这种数字还有不少,数学上把它们称为卡尔麦克数,现在数学家们已经找到所有1016以内的卡尔麦克数,最大的一个是9585921133193329。我们必须寻找更为有效的测试方法。数学家们通过对费马小定理的研究,并加以扩展,总结出了多种快速有效的素数测试方法,目前最快的算法是拉宾米勒测试算法,其过程如下:首先确定N是否为奇数,不是奇数的判断失败。选择T个随机整数A,并且有 0 50那么测试失误的机率就会小于10-30,这对于目前的计算机硬件来说已经足够证明N就是素数了。下面是伪代码。算法五:拉宾米勒测试法测试P是否为素数。 C := 500 ;素数表大小 S[ 0 TO C ] ;素数表 B := P - 1 T := 50 ;表示进行测试的次数 A := 0 ;用来测试通过的随机整数 FOR I := 0 TO C ;进行素数表初步测试 IF P mod S[I] = 0 RETURN FAILE END IF IF P > 1 R := R + 1 ;计算R NEXT X := 0 Y := 0 FOR I := 0 TO T A := S[ RAND() mod C ] ;先进行费马测试 IF A ^ ( P - 1 ) mod P <> 1 RETURN FAILE END IF X := A Y := A ^ ( M * R * 2 ) WHILE X <= Y IF X ^ M mod P = 1 BREAK END IF X := X ^ 2 NEXT IF X > Y RETURN FAILE END IF NEXT RETURN PASS ·二元一次不定方程在算法概述的章节里我们曾经讨论过公钥1的求法:找一个数D,使得( E * D ) mod ( ( P - 1 ) * ( Q - 1 ) ) = 1成立。为了求D,我们先对这个方程变形。实际上这个方程可以看做AX mod B = 1,即: AX = BY + 1,Y为一整数。 AX - BY = 1 这就是一个二元一次不定方程,有已知数A、B,未知数X、Y。我们现在需要求的是X,那么就是求这个方程对于X的最小整数解。由于方程有两个未知数,所以必须化简方程,使得一个未知数的系数为0时才能得解。设B > A时有: AX - BY = 1 那么可以认为B = AN + M,则有: AX - ( AN + M )Y = 1 AX - ANY - MY = 1 A( X - NY ) - MY = 1 实际上M就是B mod A的值,设X’ = X - NY,B’ = B mod A则有AX’ - B’Y = 1,且A > M成立。接着可以用同样的方法来化简A,最终必能将一个系数化为0。此时求出另一个未知数的解,再按逆序代入上一步的方程,求出另一个未知数的解,再代入上一步的方程,一直递推的第一个方程,最终即可获得X和Y的最小整数解。因为每一步递推的方程的余数相同,所以我们称这些方程为“一次同余式”。这个算法被称为欧几里德扩展算法,而欧几里德算法其实就是求公因式的辗转相除法,大多数朋友在中学时就学过了,但是我们下面会用到,所以我这里简单的用伪代码来描述一下欧几里德算法。算法六:求A和B两相异自然数的最大公因数,另R为结果。 IF A P。并且有正整数D使ND mod P = 1成立,求D。 IF N和P的最大公因数 <> 1 ;调用算法六 RETURN FAILE END IF LT := 1 ;左上 RT := N mod P ;右上 LD := 0 ;左下 RD := P ;右下 X := 0 ;中间变量 WHILE RT <> 1 X := RD / RT RD := RD % RT IF RD = 0 RD := RT LD := ( X - 1 ) * LT + LD ELSE LD := X * LT + 1 END IF X := RT / RD RT := RT % RD IF RT = 0 RT := RD LT := ( X - 1 ) * LD + LT ELSE LT := X * LD + 1 END IF NEXT D := LT ·结语到现在,RSA算法中所涉及到的所有算法我们都已经讨论过了。实际还有一个运算,就是私钥的获得办法:计算得到与( P - 1 ) * ( Q - 1 )的值互质的整数E。我情愿不把它称之为算法,因为只需要一个循环和一个判断就可以完成,所以这里也就没有必要对它多加论述了。 ·附录费马小定理的证明:引理1:设M,A的最大公约数( M,A ) = 1,且M整除AB,即M mod AB = 0,则M mod B = 0。引理2:设P是素数,
表示组合数,即从P个数中选出J个数的组合种数,且1 ≤ J ≤ P - 1,则P mod
。证明:已知组合数
= P! / ( J! * ( P - J )! )是整数,即J! * ( P - J )! mod P! = 0。由于P是素数,所以对任意1 ≤ I ≤ P-1有( P,I ) = 1。因此由引理1有( P,j! * ( P - J )! ) = 1,1 ≤ J ≤ P - 1。进而由引理1推出:当1 ≤ J ≤ P - 1时J! * ( P - J )! mod ( P - 1 )! = 0,得证。
posted on 2008-05-30 01:47
幽幽 阅读(1412)
评论(0) 编辑 收藏 引用 所属分类:
算法