要做出该题目,需要先了解RSA算法的原理。RSA算法是一种非对称加密算法,它使用两个大素数p和q来生成一个公钥和一个私钥。
RSA算法原理:RSA算法加解密原理
加密过程:
1、选择一对不相等且足够大的质数【p,q】
2、计算p,q的乘积【n=p*q】
3、计算n的欧拉函数【ol(n)=(p-1)*(q-1)】
4、选一个与ol(n)互质的整数e【1<e<ol(n)】
5、计算出e对于ol(n)的模反元素d【d*e%ol(n)=1】
6、公钥【ku=(e,n)】
7、私钥【kr=(d,n)】
8、明文M【加密 M^e % n = C】
9、密文C【解密 C^d % n = M】
注:
欧拉函数:是小于n的正整数中与n互质的数的数目
模反元素:如果两个正整数e和ol(n)互质,那么一定可以找到一个整数d,使得e*d-1能被ol(n)整除,即e*d % ol(n) = 1。此时d就叫做e的模反元素。【与逆元运算是同一概念】
实现代码:
from gmpy2 import *
from sympy import nextprime
# 根据题目提供的代码可知:n、密文c、公钥e,需要通过n、c、e还原出明文m,然后再将m转换为flag。
# 1、根据n计算出模糊的r值;
# 2、根据r值得到p、q;
# 3、根据p、q计算出欧拉函数值;
# 4、根据欧拉函数值和公钥e计算出私钥d;
# 5、根据私钥d对密文c进行解密,得到明文m;
# 6、将明文m转换为flag。
n = 1058756604181685917958185571746711428601045466594619627088399455470892502310139608978164573773765910533535849969889860275644658086339362201840191861497991951344100284004205747279828567835277683
c = 643011921358774538378881505518732362708757638007688649119354348647468190640688857686213431516881297805187671774564672497176686191162897918672339254715366498963369868410476737543157157149810569
e = 65537
# 1、根据n计算出模糊的r值;因为n值非常大,n值主要受r^5影响,其他影响大小就不考虑了
# p1 ≈ r^5
# q1 ≈ r^5
# n ≈ (r^5) * (r^5) = r^10
# 计算n的第10次方根,得到r的近似值
r_near = gmpy2.iroot(n, 10)[0]
# 2、根据r值得到p、q;
# 循环遍历r的附近值,找到满足条件的p和q【如果不在此范围(r_near - 100, r_near + 100)可进行扩大】
for r in range(r_near - 100, r_near + 100):
p1 = r**5 + r**4 - r**3 + r**2 - r + 2024
q1 = r**5 - r**4 + r**3 - r**2 + r + 2024
p = nextprime(p1)
q = nextprime(q1)
if p * q == n:
# 3、根据p、q计算出欧拉函数值;
# 计算欧拉函数值
L = (p - 1) * (q - 1)
# 4、根据欧拉函数值和公钥e计算出私钥d;【d*e%ol(n)=1】
# 计算私钥:逆元运算,即求e对于L的模反元素d,满足d*e%L=1
d = gmpy2.invert(e, L)
# 5、根据私钥d对密文c进行解密,得到明文m;
# 解密:C^d % n = M
m = pow(c, d, n)
# 6、将明文m转换为flag。
# 此时明文m还是是一个大整数,需要将其转换为字节串【即8位一字节的二进制数】,然后再解码为字符串。
# m.bit_length()+7)//8 :计算出m转换为字节串所需的字节数。【bit_length:计算大整数 m 的位数;+7//8是为了向上取整得到字节数】
# m.to_bytes(length, byteorder='big'):将整数m转换为字节串。【length需要是字节数;byteorder='big'表示大端字节序,高位字节在前】
print(m.to_bytes((m.bit_length()+7)//8, byteorder='big'))
break
2375

被折叠的 条评论
为什么被折叠?



