RSA-python编程简单实现
RSA_python简单编程实现
一.RSA算法简述
rsa算法是一种非对称加密算法,其安全性是建立在大素数难以分解的基础上的,即将两个大素数相乘十分容易,但想对其乘积进行分解却很困难,所以可以将其乘积公开作为加密密钥
二. 密钥生成过程
1.选择两个大素数p和q
2.计算两素数的乘积 n =p*q,和Φ(n)=(p-1)(q-1)
3.选择大于1并且小于Φ(n)的随机整数e,使得gcd(e,Φ(n))=1
4.计算e在modΦ(n)下的乘法逆元d
5.最后得出公钥为(e,n),私钥为(d,n)
三. RSA加解密过程
1. 加密
对于明文M,则有密文C=M^e mod n
2. 对于密文C,则有明文M=C^d mod n
声明:以上理论来自该处
四.python实现简易RSA算法
– 在了解了RSA算法的基本的工作流程,那么就可以编写代码了
– 话不多说看代码
def encryption(m, e, n):
s = m % n
for i in range(1, e):
s = (s * (m % n)) % n
print('你所加密的密文是:', s)
# 解密
def decode(c, d, n):
s = c % n
for i in range(1, d):
s = (s * (c % n)) % n
print('你所解密的明文是:', s)
# p,q,e质数判断
def apnjudg(p, q, e):
list = []
list.append(p)
list.append(q)
list.append(e)
for x in range(0, 3):
if int(list[x]) > 1:
# 查看因子
for i in range(2, int(list[x])):
if (int(list[x]) % i) == 0:
print(int(list[x]), "不是质数")
print(i, "乘于", int(list[x]) / i, "是", int(list[x]))
break
else:
print(int(list[x]), "是质数")
break
# 如果输入的数字小于或等于 1,不是质数
else:
print(int(list[x]), "不是质数")
# 拆解获得素数p,q
def broken(n):
if n < 10000000:
for i in range(1, 10000):
for t in range(1, 10000):
if n == i * t:
print(i, t)
break
if __name__ == '__main__':
num = int(input('请输入你的选择的功能-RSA加密为0,RSA解密为1,分解查找P与Q为2:'))
if num == 0:
print('----------------加密----------------')
print('---------请输入P,Q,E,M(明文)---------')
p = int(input('输入P:'))
q = int(input('输入Q:'))
e = int(input('输入E:'))
apnjudg(p, q, e)
m = int(input('请输入M:'))
encryption(m, e, p * q)
elif num == 1:
print('----------------解密----------------')
print('---------请输入P,Q,E,C(密文)---------')
p = int(input('输入P:'))
q = int(input('输入Q:'))
e = int(input('输入E:'))
fi = (p - 1) * (q - 1)
for i in range(fi): #求逆元d
if e * i % fi == 1:
d = i
break
apnjudg(p, q, d)
c = int(input('请输入C:'))
decode(c, d,p * q)
elif num == 2:
print('----------------拆解素数乘积----------------')
n = int(input('输入乘积N:'))
broken(n)
– 效果图看这
加密
解密
乘积拆解
五.代码不足之处说明及汇总
不足之处
1.素数位数过短
相信各位童鞋已经看出来了,我选的两个素数都不是特别大,都是四位数,那是因为我的设备不太行,跑五位数的素数要跑比较长的时间,而且我代码中所用实现算法的方法也很随意,是在上课时随意打的😂😂😂,if,else语句比较多…大佬勿喷!!!,没有用上什么高大上的语法,各位童鞋有什么好的建议,能够优化一下该算法的,可以在评论区留言,我看看我能够改成什么样。
我选的素数乘积是在10000000以下,这样所采用的两个素数也很容易猜解,两个循环就能找到,而RSA算法的核心就在于,大素数乘积难以分解,所以我写的代码,各位童鞋就当作是个简单测验吧
2.加密类型转换过于直接
我是直接将用户输入强制转换为整形数据的,因为我加密的文本类型就是整型数据,所以我就没考虑如何转换其它类型的数据,如字符型数据等等
汇总
我在想这个实现加解密算法的方法可不可以用一个简易的图形化窗口来实现,并且能够在优化之后运算出更大位数的素数,嗯…这个等待后续吧
代码功能详解
(一)
咱们先看第一个加密函数里的参数m(你所要加密的明文)e(大于1并且小于Φ(n)的随机整数e使得gcd(e,Φ(n)))=1,Φ(n)=(p-1)*(q-1) #p和q均为大素数gcd(e,Φ(n)))=1 这是什么意思呢,意思就是你选取的e与Φ(n)的公约数为一,简单的来说e与Φ(n)互素,所以e为素数—->我用了一个素数判断函数
apnjudg(p, q, e)n=p * q
(二)
接着咱们来看加密函数对于明文M,则有密文C=M^e mod n,我们可以根据这个公式加密得出密文,M^e的结果,也就是e个M相乘(MMM*M…)—–>这里我们可以用for循环做到for i in range(1,e),然后有该幂次的结果模N——>(%n)就得到了密文C功能代码如下
s = m % n
for i in range(1, e):
s = (s * (m % n)) % n
(三)
解密密钥d,在讲解解密函数之前,我们先讲讲如何得到d
由一个函数de=1 mod Φ(n)—->即满足条件(de)%Φ(n)=1, 我们可以将d求出来(这个公式用到了欧拉定理)
根据公式我们就好求d了,d即e的逆元
功能代码如下:
for i in range(fi): #求逆元d
if e * i % fi == 1:
d = i
break