RSA公钥加密算法

184 阅读2分钟

「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」。

简介

最初的公钥方案RSA是1997年由Ron Rivest、Adi Shamir和Leonard Adleman在MIT开发,称为现在最广泛接受的公钥加密方法。RSA是分组加密,对于某个自然数n,它的明文和密文是0n10 \sim n - 1之间的某个整数。 对于明文分组P和密文分组C,RSA的加密和解密形式如下: C=PemodnC = P^e\bmod n P=Cdmodn=(Pe)dmodn=PedmodnP = C^d\bmod n=(P^e)^d\bmod n=P^{ed}\bmod n

要求

发送方和接收方都必须知道nnee的值,并且只有接收方知道dd的值。RSA的公钥PK=(e,n)PK=(e,n),私钥SK=(d,n)SK=(d,n)。为了该算法能够满足公钥加密要求,必须满足下列条件:

  1. 可以找到e,d,ne,d,n的值,使得对所有的M<n,Med=MmodnM<n,M^{ed}=M\bmod n成立;
  2. 对所有满足M<nM<n的值,计算MeM^eCdC^d相对容易;
  3. 给定eenn,不可能推导出dd

前两个要求很容易满足,当eenn取很大的值时,第三个要求也能够满足。

算法

RSA的算法过程具体如下:

  1. 选择两个很大的素数pqp和q,计算他们的乘积nn作为加密和解密的模;
  2. 计算nn的欧拉函数值ϕ(n)=(p1)(q1)\phi (n) = (p - 1)(q - 1),表示小于nn并且与nn互素的正整数的个数;
  3. 选择整数e,e<ne,e<n并且eeϕ(n)\phi(n)互素,即gcd(e,ϕ(n))=1gcd(e,\phi(n))=1
  4. 计算dd,它是ee关于模ϕ(n)\phi(n)的乘法逆元,即demodϕ(n)=1de\bmod \phi(n)=1
    de=kϕ(n)+1(kZ+)de=k\phi(n)+1(k\in Z^+)

Python实现

已知e,d,ne,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,7715,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的方法:

  • 穷举

尝试所有的私钥,所以eedd的值越大,算法越安全,但是密钥太长会导致计算量太大。

  • 因式分解

通过因式分解nn为两个素质,但是当ppqq很大时,因式分解问题十分困难,目前一般采用1024,2048或4096比特的密钥,如此长度的密钥对于当今所有应用可以认为强度足够。