RSA算法数学理论、例子与模幂周期性攻击
RSA是一种非对称加密算法,基于特殊大整数(两素数乘积)的因式分解难题保证安全性。
生成密钥的步骤如下:
1、选择大素数p,q。为最大限度提高安全性,要求p与q的位数相当;
2、计算n = p * q。n称为模,modules,我们通常说的1024位密钥,指的是n为1024位,即128字节;
3、计算欧拉函数 Ø(n) = (p-1) * (q-1)。因为n为两素数p,q之积;
4、选择公钥参数e,与Ø(n) 互素。常用的e有3、17及65537;
5、求私钥参数d,满足 e * d ≡ 1 mod Ø(n) ;
6、公钥为n,e。私钥为n,d。p和q将不参与加解密运算;
公钥(n,e)加密 message -> cipher: c ≡ m ^ e mod n
私钥(n,d)解密 cipher -> message: m ≡ c ^ d mod n
证明很简单,这也是RSA的数学美感所在:
e * d = 1 mod (n)
=> e * d = 1 mod (p-1)*(q-1)
=> e * d = 1 mod (p-1), AND e * d = 1 mod (q-1)
=> m ^ (e * d) = m mod p, AND m ^ (e * d) = m mod q
=> m ^ (e * d) = m mod (p * q)
对于裸签名,原理上就是将上面的m和c调换,使用私钥加密,公钥解密。需要注意的是,PKI中的数字签名并不仅仅是裸签名。
附上一段POC:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
author: xjump.me#gmail.com
reference:
http://code.activestate.com/recipes/572196-rsa/
'''
def egcd(a,b):
# Extended Euclidean Algorithm
# returns x, y, gcd(a,b) such that ax + by = gcd(a,b)
u, u1 = 1, 0
v, v1 = 0, 1
while b:
q = a // b
u, u1 = u1, u - q * u1
v, v1 = v1, v - q * v1
a, b = b, a - q * b
return u, v, a
def modInverse(e,phi_n):
return egcd(e,phi_n)[0]%phi_n
def main():
p = 79
q = 87
n = p*q
phi_n = (p-1)*(q-1)
e = 19
d = modInverse(e,phi_n)
print "p=%d, q=%d, n=%d, e=%d, phi_n=%d, d=%d" % (p,q,n,e,phi_n,d)
m = 30
c = (m**e) % n # encrypt by public key (n,e)
m1 = (c**d) % n # decrypt by private key (n,d)
print "message is %d, cipher is %d, cipher decrypt out is %d" % (m, c, m1)
print "\n================start encryption loops attack."
save_c = None
c1 = c
while True:
m = c1
c1 = (m**e) % n
save_c = m
print "message is %d, cipher is %d" % (m, c1)
if c1 == c:
print "==================got it! after some encryption loops, m is %d" % (save_c)
break;
main()