import math
import random
from sympy import isprime # 判断是否素数
def prime_random(start, end):
# 产生质数,范围max(start, end) < 2^64
prime_number_list = []
for prime_number in range(start, end):
if isprime(prime_number): # 如果是素数, 加入列表
prime_number_list.append(prime_number)
if not prime_number_list or max(start, end) > 2 ** 64:
print("没有找到质数,返回13")
return 13
return random.choice(prime_number_list) # 从列表随机取一个素数
def euler_phi(number):
# 概念:欧拉函数在数论,对正整数n,欧拉函数φ(n)是小于n的正整数中与n互质的数的数目,以φ(n)表示欧拉函数
# 在1—10中,与10互质的有1、3、7、9,即φ(10)=4。
euler_num = 0
for i in range(1, number):
if math.gcd(i, number) == 1:
euler_num += 1
return euler_num
def RSA_Verification_testing(): # RSA 验证过程
# RSA 看百度百科的算法描述即可: https://baike.baidu.com/item/RSA%E7%AE%97%E6%B3%95/263310?fromtitle=RSA&fromid=210678&fr=aladdin
# RSA密钥 (PublicKey(n, e), PrivateKey(n, e, d, p, q))
# 1.任意选取两个不同的大素数(质数)p和q, 计算乘积 n = pq, 注意p与q不能相等
# 概念:质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
p = prime_random(7, 1024) # 获取一个随机质数
q = prime_random(13, 1024) # 获取一个随机质数
while p == q:
p = 7 # 7
q = 13 # 13
print(f"质数:p:{p},q:{q}")
n = p * q # 91
print(f"模长n:{n}")
# 2.计算n的欧拉函数φ(n), https://blog.51cto.com/u_15400016/4287468
# 概念:欧拉函数在数论,对正整数n,欧拉函数φ(n)是小于n的正整数中与n互质的数的数目,以φ(n)表示欧拉函数
# 在1—10中,与10互质的有1、3、7、9,即φ(10)=4。
# 如果n是质数,则φ(n)=n-1 。因为质数与小于它的每一个数,都构成互质关系。比如7与1、2、3、4、5、6都构成互质关系,φ(7) = 7-1。
# 由互质关系能得出以下结论:n = p1 × p2,则φ(n) = φ(p1p2) = φ(p1)φ(p2)=(p1-1)*(p2 -1) , φ(n) = φ(p1p2) = φ(3)φ(7)=2*6=12
# print(euler_phi(21)) # euler_phi欧拉函数
fn = (p - 1) * (q - 1) # 72
# 3.任意选取一个大整数e(公钥),满足gcd(e, φ(n)) = 1;整数e用做加密钥(注意:e的选取是很容易的,例如,所有大于p和q的素数都可用, 实际应用通常取65537)
# 概念:最大公因数,也称最大公约数、最大公因子,指两个或多个整数共有约数中最大的一个,如(12,15,18)=3
for e in range(max(p, q) + 1, n):
if math.gcd(e, fn) == 1: # Python math.gcd() 方法返回给定的整数参数的最大公约数
break
print(f"公钥e:{e}, 是否素数{isprime(e)}")
# 4.确定解密密钥d(私钥),满足(d*e) mod φ(n) = 1 (或d*e = k*φ(n) + 1, k为k≥1的任意整数)
for d in range(int((fn+1)/e), n):
if (d * e) % fn == 1:
break
print(f"私钥d:{d}, 是否素数{isprime(d)}")
# 5.加密算法c = E(m) = m**e mod n,使用公钥 e 对明文 m 进行加密-----公钥加密(注意 m 需小于 n )
m = random.randint(1, n - 1)
print(f"明文:{m}")
em = (m ** e) % n # 加密
print(f"公钥e加密:{em}")
# 6.解密算法m = D(c) = c**d mod n, 使用私钥 d 对密文 em 进行解密-----私钥解密
dm = (em ** d) % n # 解密
print(f"私钥d解密:{dm}")
if m != dm:
print("数据对比错误,(PublicKey(n, e), PrivateKey(n, e, d, p, q))")
return {"m": m, "em": em, "dm": dm, "n": n, "e": e, "d": d, "p": p, "q": q}
# 7.使用私钥 d 对明文 m 进行加密-----私钥加密(注意 m 需小于 n )
# m = random.randint(1, n-1)
print(f"明文:{m}")
em = (m ** d) % n # 加密
print(f"私钥d加密:{em}")
# 8.使用公钥 e 对密文 em 进行解密-----公钥解密
dm = (em ** e) % n # 解密
print(f"公钥e解密:{dm}")
if m != dm:
print("数据对比错误,(PublicKey(n, e), PrivateKey(n, e, d, p, q))")
return {"m": m, "em": em, "dm": dm, "n": n, "e": e, "d": d, "p": p, "q": q}
if __name__ == '__main__':
# print(int("002".encode(), 16))
import rsa
(pub_key, priv_key) = rsa.key.newkeys(1024) # 生成密钥 (PublicKey(n, e), PrivateKey(n, e, d, p, q))
print(f"RSA公钥n:{pub_key.n},公钥e:{pub_key.e}, 模长{rsa.common.byte_size(pub_key.n)}")
print(f"RSA私钥n:{priv_key.n},私钥e:{priv_key.e},私钥d:{priv_key.d},私钥p:{priv_key.p},私钥q:{priv_key.q}, 模长{rsa.common.byte_size(pub_key.n)}")
data = RSA_Verification_testing()
print("{:0256X}".format(priv_key.e), "{:0256X}".format(priv_key.d), "{:0256X}".format(priv_key.n))
# print(f"模长{rsa.common.byte_size(data['n'])}")
exit(0)
for i in range(1000):
data = RSA_Verification_testing()
if data:
print(f"-------第{i}次出错了,{data}-------")
print(
f"'e':{isprime(data['e'])}, 'd':{isprime(data['d'])},'p':{isprime(data['p'])},'q':{isprime(data['q'])}")
break
RSA算法知识详解与验证__文章2
于 2023-04-09 23:45:24 首次发布