简介
最初的公钥方案RSA是1997年由Ron Rivest、Adi Shamir和Leonard Adleman在MIT开发,称为现在最广泛接受的公钥加密方法。RSA是分组加密,对于某个自然数n,它的明文和密文是
0
∼
n
−
1
0 \sim n - 1
0∼n−1之间的某个整数。
对于明文分组P和密文分组C,RSA的加密和解密形式如下:
C
=
P
e
m
o
d
n
C = P^e\bmod n
C=Pemodn
P
=
C
d
m
o
d
n
=
(
P
e
)
d
m
o
d
n
=
P
e
d
m
o
d
n
P = C^d\bmod n=(P^e)^d\bmod n=P^{ed}\bmod n
P=Cdmodn=(Pe)dmodn=Pedmodn
要求
发送方和接收方都必须知道 n n n和 e e e的值,并且只有接收方知道 d d d的值。RSA的公钥 P K = ( e , n ) PK=(e,n) PK=(e,n),私钥 S K = ( d , n ) SK=(d,n) SK=(d,n)。为了该算法能够满足公钥加密要求,必须满足下列条件:
- 可以找到 e , d , n e,d,n e,d,n的值,使得对所有的 M < n , M e d = M m o d n M<n,M^{ed}=M\bmod n M<n,Med=Mmodn成立;
- 对所有满足 M < n M<n M<n的值,计算 M e M^e Me和 C d C^d Cd相对容易;
- 给定 e e e和 n n n,不可能推导出 d d d。
前两个要求很容易满足,当 e e e和 n n n取很大的值时,第三个要求也能够满足。
算法
RSA的算法过程具体如下:
- 选择两个很大的素数 p 和 q p和q p和q,计算他们的乘积 n n n作为加密和解密的模;
- 计算 n n n的欧拉函数值 ϕ ( n ) = ( p − 1 ) ( q − 1 ) \phi (n) = (p - 1)(q - 1) ϕ(n)=(p−1)(q−1),表示小于 n n n并且与 n n n互素的正整数的个数;
- 选择整数 e , e < n e,e<n e,e<n并且 e e e与 ϕ ( n ) \phi(n) ϕ(n)互素,即 g c d ( e , ϕ ( n ) ) = 1 gcd(e,\phi(n))=1 gcd(e,ϕ(n))=1;
- 计算
d
d
d,它是
e
e
e关于模
ϕ
(
n
)
\phi(n)
ϕ(n)的乘法逆元,即
d
e
m
o
d
ϕ
(
n
)
=
1
de\bmod \phi(n)=1
demodϕ(n)=1,
则 d e = k ϕ ( n ) + 1 ( k ∈ Z + ) de=k\phi(n)+1(k\in Z^+) de=kϕ(n)+1(k∈Z+)。
Python实现
已知 e , d , n e,d,n e,d,n,即已知公钥私钥,求加解密的结果
s=input('please input e,d,n:\n')
num=s.split(' ')
e=int(num[0])
d=int(num[1])
n=int(num[2])
print('PK=(%d,%d)\nSK=(%d,%d)\n'%(e,n,d,n))
while True:
try:
choice=input('input 1 or 2:\n1.Encode\n2.Decode\n')
code=int(input('please input your message(integer):\n'))
if choice=='1':
print('C =',(code**e)%n)
else:
print('P =',(code**d)%n)
except IOError:
break
输入输出样例
输入 5 , 22 , 771 5,22,771 5,22,771之后的信息如下:
please input e,d,n:
5 77 221
PK=(5,221)
SK=(77,221)
input 1 or 2:
1.Encode
2.Decode
输入1加密54得到175
1
please input your message(integer):
54
C = 175
输入2解密175得到54
2
please input your message(integer):
175
P = 54
可以看到54加密为175,175解密为54,算法验证正确
破解
存在两种可能攻击RSA的方法:
- 穷举
尝试所有的私钥,所以 e e e和 d d d的值越大,算法越安全,但是密钥太长会导致计算量太大。
- 因式分解
通过因式分解 n n n为两个素质,但是当 p p p和 q q q很大时,因式分解问题十分困难,目前一般采用1024,2048或4096比特的密钥,如此长度的密钥对于当今所有应用可以认为强度足够。