[这个贴子最后由lp乌鸦在 2004/04/12 08:36am 第 1 次编辑]
它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, Adi Shamir 和Leonard Adleman。但RSA的安全性一直未能得到理论上的证明。它经历了各种攻击,至今未被完全攻破。
一、RSA算法 :
首先, 找出三个数, p, q, r,
其中 p, q 是两个相异的质数, r 是与 (p-1)(q-1) 互质的数......
p, q, r 这三个数便是 private key
接著, 找出 m, 使得 rm == 1 mod (p-1)(q-1).....
这个 m 一定存在, 因为 r 与 (p-1)(q-1) 互质, 用辗转相除法就可以得到了.....
再来, 计算 n = pq.......
m, n 这两个数便是 public key
编码过程是, 若资料为 a, 将其看成是一个大整数, 假设 a < n....
如果 a >= n 的话, 就将 a 表成 s 进位 (s <= n, 通常取 s = 2^t),
则每一位数均小於 n, 然後分段编码......
接下来, 计算 b == a^m mod n, (0 <= b < n),
b 就是编码後的资料......
解码的过程是, 计算 c == b^r mod pq (0 <= c < pq),
於是乎, 解码完毕...... 等会会证明 c 和 a 其实是相等的 :)
如果第三者进行窃听时, 他会得到几个数: m, n(=pq), b......
他如果要解码的话, 必须想办法得到 r......
所以, 他必须先对 n 作质因数分解.........
要防止他分解, 最有效的方法是找两个非常的大质数 p, q,
使第三者作因数分解时发生困难.........
<定理>
若 p, q 是相异质数, rm == 1 mod (p-1)(q-1),
a 是任意一个正整数, b == a^m mod pq, c == b^r mod pq,
则 c == a mod pq
证明的过程, 会用到费马小定理, 叙述如下:
m 是任一质数, n 是任一整数, 则 n^m == n mod m
(换另一句话说, 如果 n 和 m 互质, 则 n^(m-1) == 1 mod m)
运用一些基本的群论的知识, 就可以很容易地证出费马小定理的........
<证明>
因为 rm == 1 mod (p-1)(q-1), 所以 rm = k(p-1)(q-1) + 1, 其中 k 是整数
因为在 modulo 中是 preserve 乘法的
(x == y mod z and u == v mod z => xu == yv mod z),
所以, c == b^r == (a^m)^r == a^(rm) == a^(k(p-1)(q-1)+1) mod pq
1. 如果 a 不是 p 的倍数, 也不是 q 的倍数时,
则 a^(p-1) == 1 mod p (费马小定理) => a^(k(p-1)(q-1)) == 1 mod p
a^(q-1) == 1 mod q (费马小定理) => a^(k(p-1)(q-1)) == 1 mod q
所以 p, q 均能整除 a^(k(p-1)(q-1)) - 1 => pq | a^(k(p-1)(q-1)) - 1
即 a^(k(p-1)(q-1)) == 1 mod pq
=> c == a^(k(p-1)(q-1)+1) == a mod pq
2. 如果 a 是 p 的倍数, 但不是 q 的倍数时,
则 a^(q-1) == 1 mod q (费马小定理)
=> a^(k(p-1)(q-1)) == 1 mod q
=> c == a^(k(p-1)(q-1)+1) == a mod q
=> q | c - a
因 p | a
=> c == a^(k(p-1)(q-1)+1) == 0 mod p
=> p | c - a
所以, pq | c - a => c == a mod pq
3. 如果 a 是 q 的倍数, 但不是 p 的倍数时, 证明同上
4. 如果 a 同时是 p 和 q 的倍数时,
则 pq | a
=> c == a^(k(p-1)(q-1)+1) == 0 mod pq
=> pq | c - a
=> c == a mod pq
Q.E.D.
这个定理说明 a 经过编码为 b 再经过解码为 c 时, a == c mod n (n = pq)....
但我们在做编码解码时, 限制 0 <= a < n, 0 <= c < n,
所以这就是说 a 等於 c, 所以这个过程确实能做到编码解码的功能.....
二、RSA 的安全性
RSA的安全性依赖于大数分解,但是否等同于大数分解一直未能得到理论上的证明,因为没有证明破解 RSA就一定需要作大数分解。假设存在一种无须分解大数的算法,那它肯定可以修改成为大数分解算法。目前, RSA 的一些变种算法已被证明等价于大数分解。不管怎样,分解n是最显然的攻击方法。现在,人们已能分解多个十进制位的大素数。因此,模数n 必须选大一些,因具体适用情况而定。
三、RSA的速度
由于进行的都是大数计算,使得RSA最快的情况也比DES慢上倍,无论是软件还是硬件实现。速度一直是RSA的缺陷。一般来说只用于少量数据加密。
四、RSA的选择密文攻击
RSA在选择密文攻击面前很脆弱。一般攻击者是将某一信息作一下伪装( Blind),让拥有私钥的实体签署。然后,经过计算就可得到它所想要的信息。实际上,攻击利用的都是同一个弱点,即存在这样一个事实:乘幂保留了输入的乘法结构:
( XM )^d = X^d *M^d mod n
前面已经提到,这个固有的问题来自于公钥密码系统的最有用的特征--每个人都能使用公钥。但从算法上无法解决这一问题,主要措施有两条:一条是采用好的公钥协议,保证工作过程中实体不对其他实体任意产生的信息解密,不对自己一无所知的信息签名;另一条是决不对陌生人送来的随机文档签名,签名时首先使用One-Way HashFunction 对文档作HASH处理,或同时使用不同的签名算法。在中提到了几种不同类型的攻击方法。
五、RSA的公共模数攻击
若系统中共有一个模数,只是不同的人拥有不同的e和d,系统将是危险的。最普遍的情况是同一信息用不同的公钥加密,这些公钥共模而且互质,那末该信息无需私钥就可得到恢复。设P为信息明文,两个加密密钥为e1和e2,公共模数是n,则:
C1 = P^e1 mod n
C2 = P^e2 mod n
密码分析者知道n、e1、e2、C1和C2,就能得到P。
因为e1和e2互质,故用Euclidean算法能找到r和s,满足:
r * e1 + s * e2 = 1
假设r为负数,需再用Euclidean算法计算C1^(-1),则
( C1^(-1) )^(-r) * C2^s = P mod n
另外,还有其它几种利用公共模数攻击的方法。总之,如果知道给定模数的一对e和d,一是有利于攻击者分解模数,一是有利于攻击者计算出其它成对的e’和d’,而无需分解模数。解决办法只有一个,那就是不要共享模数n。
RSA的小指数攻击。 有一种提高 RSA速度的建议是使公钥e取较小的值,这样会使加密变得易于实现,速度有
所提高。但这样作是不安全的,对付办法就是e和d都取较大的值。
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。即RSA的重大缺陷是无法从理论上把握它的保密性能如何,而且密码学界多数人士倾向于因子分解不是NPC问题。 RSA的缺点主要有:A)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。B)分组长度太大,为保证安全性,n 至少也要 600 bits 以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个长度还在增加,不利于数据格式的标准化。目前,SET( Secure Electronic Transaction )协议中要求CA采用比特长的密钥,其他实体使用比特的密钥。
二:
RSA的原理
R.S.A.
(#rsa4newbies)
(v1.2) par Lucifer48 [Immortal Descendants]
(5 Février 2000)
Ron Rivest, Adi Shamir et Leonard Adleman ont inventé ce système en 1978. Il est basé sur la difficulté de factoriser un nombre qui est le produit de deux nombres premiers.
Sommaire:
Principe du RSA
RSA en 8 lignes
Un peu de pratique
Conclusion
RSA 由 从事发明这个方法在1987年。这个方法的难点来自因式分解(把复杂计算分解为基本运算)一个数字招致(引出)两个素数计算。
摘要:
RSA 原理
8个符号线索在RSA中
一个小的实践
总结
RSA 原理
Soient p et q, deux nombres premiers. Posons: n = p * q
Remarque: Il est conseillé de choisir des grands nombres premiers. En effet, il est facile de retrouver p et q lorque n est petit...
用两个很大的质数,p 和 q,计算它们的乘积 n = pq;n 是模数。选择一个比 n 小的数 e,它与 (p - 1)(q - 1) 互为质数,即,除了 1 以外,e 和 (p - 1)(q - 1) 没有其它的公因数。找到另一个数 d,使 (ed - 1) 能被 (p - 1)(q - 1) 整除。值 e 和 d 分别称为公共指数和私有指数。公钥是这一对数 (n, e);私钥是这一对数 (n, d)。
Remarque: 这个 PGCD (GCD 是 英语 Greatest Common Divisor最大公约数) 我们利用(古希腊数学家).欧几里得的, 欧几里得几何学 Ansi:
PGCD(a,b) = PGCD(b,a) = PGCD(b, a mod b)
et PGCD(c,0) = c
我们现在提出a 和 b 之间的关系 PGCD(a,b)=1. 在这里是也可能找出: a 存在于早期的 b.
Remarque2: 它们仅仅是倒置的来自 Z/(p-1)(q-1)Z 存在于最初的 e. 阅读这个次序可以更好地了解.
e 是非常重要的,因为它是明确的译码. 推出关键的 d (notons la d).
d = inv(e) [(p-1)*(q-1)]
<=> d = inv(e) in Z/(p-1)(q-1)Z
<=> e*d = 1 [(p-1)*(q-1)]
<=> d = e^-1 mod ((p-1)*(q-1))
利用这4个符号
我们将获得相反的 e:
e * U + ((p-1)*(q-1)) * V = PGCD(e,(p-1)*(q-1)) = 1 (U et V sont des entiers)
et donc,
U mod ((p-1)*(q-1)) = inv(e) = e^-1
事例:
31 div 13 = 2 reste 5
13 div 05 = 2 reste 3
05 div 03 = 1 reste 1
02 div 01 = 2 reste 0
PGCD(31,13)= 1;31 and 13 进入它们
1 = 3 - 2
1 = 3 - (5 - 3)
1 = 3*2 - 5
1 = 2*(13 - 5*2) - 5
1 = 2*13 - 4*5 - 5
1 = 2*13 - 5*5
1 = 2*13 -5*(31 - 13*2)
1 = 12*13 - 5*31
和关于: inv(13)=12 (in Z/31Z)
容易的引出 d.
公共钥匙: (e,n).
私有钥匙: (d,n).
Encryption: 它通知 M 加密一个数属于 Z/nZ (严格的说来自 n).
C = M^e [n]
Remarque: w 属于 Z/nZ 无论是否 w < n.
Décryption: 这是非常自然的.
M = C^d [n]
C^d = (M^e)^d = M^(ed)
de plus, e*d = 1 [(p-1)*(q-1)] <=> ed - 1 = k*(p-1)*(q-1) k est dans N*
par suite, M^(ed) = M^(k*(p-1)*(q-1) + 1)
Posons u= k*(p-1)*(q-1) + 1
si M^u = M [p] et M^u = M [q] alors, M^u = M [p*q]
et comme n=p*q, il s'ensuit que
C^d = M
Remarque: On aurait pu aussi utiliser le théorème d'Euler (mais n'est pas valable tout le temps):
Si PGCD((p-1)*(q-1),M) = 1 alors M^((p-1)*(q-1)) = 1
et donc, M^(k*(p-1)*(q-1) + 1) = M.1^k = M = C^d
(valable uniquement si (p-1)*(q-1) et M sont premiers entre eux)
RSA en 8 lignes
n = p * q (p et q sont premiers)
PGCD(e,(p-1)*(q-1)) = 1
d = e^-1 mod ((p-1)*(q-1))
(e,n): clef publique.
(d,n): clef privée.
p et q ne servent plus...
M^e mod n = M_crypté (M < n)
M_crypté^d mod n = M
Un peu de pratique
Pour tous les calculs, j'ai utilisé le logiciel Mathematica. Petit aperçu:
in[1]:=
PrimeQ[2000]
out[1]=
False
in[2]:=
{ Prime[1], Prime[2], Prime[3], Prime[4], Prime[2000] }
out[2]=
{ 2, 3, 5, 7, 17389 }
in[3]:=
PowerMod[157,-1,2668]
out[3]=
17
in[4]:=
Mod[1234^31,466883]
out[4]=
446798
in[5]:=
FactorInteger[519920418755535776857] //Timing
out[5]=
{13.35 Second, {{22801763489, 1}, {22801763513, 1}}}
in[6]:=
Needs["NumberTheory`FactorIntegerECM`"]
in[7]:=
$Packages
out[7]=
{NumberTheory`FactorIntegerECM`, Global`, System`}
in[8]:=
FactorIntegerECM[519920418755535776857] //Timing
out[8]=
{3.07 Second, 22801763513}
in[9]:=
breakRSA[x_]:= Module[{i}, i=FactorIntegerECM[x]; List[i, x/i] ]
in[10]:=
breakRSA[519920418755535776857] //Timing
out[10]=
{3.07 Second, {22801763513, 22801763489}}
in[11]:=
GCD[31,13]
out[11]=
1
in[12]:=
ExtendedGCD[31,13]
out[11]=
{1, {-5, 12}}
Remarque (重要的): 对于计算它们的类型: a^b [n] (b 正数), ne surtout pas utiliser la fonction Mod[a^b, n] mais PowerMod[a,b,n] qui est carrément plus rapide.
Quelques exemples:
*
p = 113 ; q = 541 ; n = p * q = 61133 ; (p-1)*(q-1) = 60480.
Je choisis e = 121 (GCD[121,60480]=1)
inv(e) = 57481 (inférieur à (p-1)*(q-1)) donc d = 57481.
Pour crypter M=1234567890, je dois donc découper M en petits morceaux de longueur
inférieur à n (4 est ici le maximum): M1=1234, M2=5678, M3=90.
C1 = M1^e [n] = 1234^121 [61133] = 40691
C2 = M2^e [n] = 5678^121 [61133] = 19203
C3 = M3^e [n] = 90^121 [61133] = 32121
C = 406911920332121
Pour décrypter, je découpe le message (crypté) en morceaux de longueur n (ici 5).
M1 = C1^d [n] = 40691^57481 [61133] = 1234
M2 = C2^d [n] = 19203^57481 [61133] = 5678
M3 = C3^d [n] = 32121^57481 [61133] = 90
M = 1234567890
*
p = 3571 ; q = 7919 ; n = p * q = 28278749 ; (p-1)*(q-1) = 28267260.
Je choisis e = 213889 (GCD[213889,28267260]=1)
inv(e) = 2241409 (inférieur à (p-1)*(q-1)) donc d = 2241409.
M ="Hello world" = 7210110810811132119111114108100, je découpe en morceaux de longueur 7:
M1 = 7210110, M2 = 8108111, M3 = 3211911, M4 = 1114108, M5 = 100.
C1 = M1^e [n] = 7210110^213889 [28278749] = 12840449
C2 = M2^e [n] = 8108111^213889 [28278749] = 16339096
C3 = M3^e [n] = 3211911^213889 [28278749] = 25181491
C4 = M4^e [n] = 1114108^213889 [28278749] = 24666021
C5 = M5^e [n] = 100^213889 [28278949] = 17846443
C = 1284044916339096251814912466602117846443
On découpe le C en morceaux de 8 chiffres.
M1 = C1^d [n] = 12840449^2241409 [28278749] = 7210110
M2 = C2^d [n] = 16339096^2241409 [28278749] = 8108111
M3 = C3^d [n] = 25181491^2241409 [28278749] = 3211911
M4 = C4^d [n] = 24666021^2241409 [28278749] = 1114108
M5 = C5^d [n] = 17846443^2241409 [28278749] = 100
M = 7210110810811132119111114108100
*
p = 10007 ; q = 53239 ; n = p * q = 532762673 ; (p-1)*(q-1) = 532699428.
Je choisis e = 17 (GCD[17,532699428]=1)
inv(e) = 62670521 (inférieur à (p-1)*(q-1)) donc d = 62670521.
M = 123
C = M^e [n] = 123^17 [532762673] = 270099428
M = C^d [n] = 270099428^62670521 [532762673] = 123
in[1]:=
solveRSA[n_, e_]:= Module[{j}, j=breakRSA[n]; PowerMod[e, -1, (First[j]-1)*(Last[j]-1)]]
in[2]:=
solveRSA[532762673, 17]
out[2]=
Out[12]= 62670521
总结
[一下总结明天再译] [来朋友了]
RSA确实存在着这样的一个不完美体系,它是不确定的存在缺陷于它的基础原理,他选择来自 e and d 的算法没有成熟存在着反相的偶然性,无论如何,在这里它是令人惊讶的简单,脆弱。
告诫一些程序尽量不要使用它来加密数据,尽管反相的推断它存在着很大的偶然性,在这里它还是表现得很脆弱。[下面是感谢的话,我不译了]
Greetings: All ID members (Volatility, Torn@do, alpine, ...), SiFLyiNG, Eternal Bliss, ACiD BuRN, Duelist, LaZaRuS, ... and wonderful people in #cracking4newbies & #win32asm (WazerPup, X-Calibre, MisterE, ...).
(c) Lucifer48. All rights reserved & reversed