RSA算法的流程很简单:
下面来分析实际实现中的问题:
1.第一步pq的选取,pq通常在10^100量级,可以先随机选择一个数,判断是否是素数,不是的话向旁边扩展,具体可以查阅相关资料,本程序直接给出
2.第四步,找一个e与f(n)互质,这个e通常取65537,事实上选pq的时候注意生成的f(n)要与e互质
3.第五步求d的过程:de≡1 mod f(n)可以写成de+kf(n)=1,用语言描述就是de除以f(n)的余数为1等价于de加上k倍的f(n)等于1
de+kf(n)=1我们要这个方程来计算d,显然只有一个方程,里边有d和k两个未知数,这个方程有无数组解,可以证明在1~f(n)范围的整数的d只有一个,关于这个方程的具体解答用到了扩展欧拉函数,网上有很多材料不是很清晰,具体可以看这个网站扩展欧拉函数,推导很基础,可以亲自动手推导一下
4.第七步和第八步,加解密过程一个大数的大次幂是不可能表达出来的,其次高次幂的运算也是很费时的,有算法基础的同学很容易想到快速幂,不会的同学可以查一下,很基础也很实用,同时每次运算都对n取余就可以避免数值过大溢出,具体可以看程序中这个函数
5.加密分组的设置:明文要分成组进行加密,不够组长的需要填充,
明文最大长度=密钥长度-11,单位是字节
下面是具体代码:
def gcd(a,b):
if b==0:
return a
else:
return gcd(b,a%b)
def extendGcd(a, b): #这里的扩展欧几里得算法是gcd==1的特例
if b == 0:
x = 1
y = 0
return x, y
else:
x1, y1 = extendGcd(b, a % b)
x = y1
y = x1 - (int)(a / b) * y1
return x, y
def fastMul(a,b,n):
res=1
while b!=0:
if b%2==0:
b=b/2
a=(a*a)%n
elif b%2!=0:
b=b-1
res=(res*a)%n
return res
def generateKey(p, q):
n = p * q
fn = (p - 1) * (q - 1)
e = 7 #e一般直接指定65537
x, y = extendGcd(e, fn)
if x < 0: #需要1到n之间的特解,可以证明只有一个
x = x + fn
d = x
return (n, e),(n, d)
def encrypt(m, publicKey):
n = publicKey[0]
e = publicKey[1]
c = fastMul(m, e, n)
return c
def decrypt(c, privateKey):
n = privateKey[0]
d = privateKey[1]
m = fastMul(c, d, n)
return m
p = 3
q = 11
publicKey, privateKey = generateKey(p, q)
m = 25
print("被加密明文:%s" % m)
c = encrypt(m, publicKey)
print("加密后密文:%s" % c)
d = decrypt(c, privateKey)
print("解密后明文:%s" % d)
这里用的课本上的例子,pq选取较小,也没有使用分组,仅用于测试,大家可以用大数进行测试,不过对于特别大的数要进行分组