算法描述就不用说了,其他博客都有,直接上代码:
import random
import sys
sys.setrecursionlimit(100000) #设置迭代次数限制
def main():
p = BigPrime()
q = BigPrime()
n = p*q
_n = (p-1)*(q-1)
e = 0
m = ""
while(1):
e = random.randint(1, _n+1)
if gcd(e, _n)==1:
break
d = Ex_Euclid(e, _n)
print('RSA加密算法开始!\n随机生成的大素数p为', p, '\n随机生成的大素数q为', q, '\n它们的乘积n是', n, '\n随机生成的e为', e, '\n用欧几里得算法可算出d为', d)
m = input('现在请输入你的明文:')
print('加密中。。。')
c = encrypt(m, e, n)
print('加密成功!密文是:', c)
flag = input('现在请输入1开始解密:')
if(flag != '1'):
print("字数输入错误!")
return 0
print('解密中。。。')
m1 = decrypt(c, d, n)
print('解密成功!明文是:', m1)
def MRF(b,n,m):
a=1
x=b;y=n;z=m
binstr = bin(n)[2:][::-1] #通过切片去掉开头的0b,截取后面,然后反转
for item in binstr:
if item == '1':
a = (a*b)%m
b = (b**2)%m
elif item == '0':
b = (b**2)%m
return a
def MillerRabin(n):
m = n - 1
k = 0
while(m%2==0):
m = m // 2
k += 1
a = random.randint(2,n)
b = MRF(a, m, n)
if(b==1):
return 1
for i in range(k):
if(b==n-1):
return 1
else:
b = b * b % n
return 0
def BigPrime():
Min = 10 ** 22; Max = 10 ** 30; p = 0
while(1):
p = random.randrange(Min, Max, 1)
for i in range(20):
if MillerRabin(p) == 0:
break
elif i == 19:
return p
def encrypt(m,e,n):
cipher = ""
nlength = len(str(hex(n))[2:]) #计算n的16进制长度,以便分组
message = m #读取明文
for i in range(0,len(message),8):
if i==len(message)//8*8:
m = int(a2hex(message[i:]),16) #最后一个分组
m = int(a2hex(message[i:i+8]),16)
c = MRF(m,e,n)
cipher1 = str(hex(c))[2:]
if len(cipher1)!=nlength:
cipher1 = '0'*(nlength-len(cipher1))+cipher1 #每一个密文分组,长度不够,高位补0
cipher += cipher1
return cipher
def decrypt(c,d,n):
#加密之后每一个分组的长度和n的长度相同
cipher = c
message = ""
nlength = len(str(hex(n))[2:])
for i in range(0,len(cipher),nlength):
c = int(cipher[i:i+nlength],16) #得到一组密文的c
m = MRF(c,d,n)
info = hex2a(str(hex(m))[2:])
message += info
return message
def gcd(a, b):
if a%b == 0:
return b
else:
return gcd(b, a%b)
def Ex_Euclid(x,n):
r0=n
r1=x%n
if r1==1:
y=1
else:
s0=1
s1=0
t0=0
t1=1
while (r0%r1!=0):
q=r0//r1
r=r0%r1
r0=r1
r1=r
s=s0-q*s1
s0=s1
s1=s
t=t0-q*t1
t0=t1
t1=t
if r==1:
y = (t+n)%n
return y
#ascii_to_hex
def a2hex(raw_str):
hex_str = ''
for ch in raw_str:
hex_str += hex(ord(ch))[2:]
return hex_str
#hex_to_ascii
def hex2a(raw_str):
asc_str = ''
for i in range(0,len(raw_str),2):
asc_str += chr(int(raw_str[i:i+2],16))
return asc_str
if __name__ == "__main__":
main()
结果展示: