任务六:Crypto学习
内容:
① 学习RSA,掌握原理及代码实现。
② 完成题目:2020国赛初赛bd,完成WP
RSA
一、基本信息:
① RSA加密算法是一种非对称加密算法,属于公钥密码体系。广泛运用于许多场合。
② 为了提高RSA加密的保密强度,密钥长度至少为500位长,一般推荐使用1024位,在重要场合使用2048位。
二、算法说明:
① 随机选择两个不相等的质数p和q。(两个质数越大,月难以破解)
② 计算两个质数的乘积。(n = p×q,n的二进制位数就是RSA密钥的位数)
③ 计算n的欧拉函数。(φ(n) = (p-1)(q-1))
④ 随机选择一个整数e,是公钥中用来加密的数字。(要求:1<e<φ(n)且e与φ(n)互质)
⑤ 计算e相对于φ(n)的模乘反元素d。((e*d)mod φ(n) ≡ 1)
⑥ 将n和e封装成公钥,n和d封装成私钥。
三,攻击方法:
RSA算法利用乘方运算,明文以分组为单位进行加密,每个分组的二进制均小于n。收发双方均已知n发送方已知e,只有接收方已知d,公钥为{e,n},私钥为{d,n}。该算法主要用于公钥密码加密。
① 穷举攻击法:穷举出所有的可能的私钥
② 数字攻击法:使用数学定理来攻击的方法,实质都是试图分解出两个素数的乘积。
③ 选择密文攻击:利用RSA的性质进行攻击。
题目复现
先看题目
from secret import flag
from Crypto.Util.number import *
m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
N = p * q
phi = (p-1) * (q-1)
while True:
d = getRandomNBitInteger(200)
if GCD(d, phi) == 1:
e = inverse(d, phi)
break
c = pow(m, e, N)
print(c, e, N, sep='\n')
# 37625098109081701774571613785279343908814425141123915351527903477451570893536663171806089364574293449414561630485312247061686191366669404389142347972565020570877175992098033759403318443705791866939363061966538210758611679849037990315161035649389943256526167843576617469134413191950908582922902210791377220066
# 46867417013414476511855705167486515292101865210840925173161828985833867821644239088991107524584028941183216735115986313719966458608881689802377181633111389920813814350964315420422257050287517851213109465823444767895817372377616723406116946259672358254060231210263961445286931270444042869857616609048537240249
# 86966590627372918010571457840724456774194080910694231109811773050866217415975647358784246153710824794652840306389428729923771431340699346354646708396564203957270393882105042714920060055401541794748437242707186192941546185666953574082803056612193004258064074902605834799171191314001030749992715155125694272289
从题目可知p和q是系统随机生成的大的随机素数,N为p与q的乘积,phi是N的欧拉函数,d是1到200内的一个随机数,且满足与phi互素的要求,e是d与phi的模乘反函数((e*d) mod phi ==1),c=m^e mod N。题目最后三行大数字分别是c,e,N输出的值。
解题代码如下:
import ContinuedFractions, Arithmetic, RSAvulnerableKeyGenerator
from Crypto.Util.number import long_to_bytes
def hack_RSA(e,n):
'''
Finds d knowing (e,n)
applying the Wiener continued fraction attack
'''
frac = ContinuedFractions.rational_to_contfrac(e, n)
convergents = ContinuedFractions.convergents_from_contfrac(frac)
for (k,d) in convergents:
#check if d is actually the key
if k!=0 and (e*d-1)%k == 0:
phi = (e*d-1)//k
s = n - phi + 1
# check if the equation x^2 - s*x + n = 0
# has integer roots
discr = s*s - 4*n
if(discr>=0):
t = Arithmetic.is_perfect_square(discr)
if t!=-1 and (s+t)%2==0:
print("Hacked!")
return d
# TEST functions
if __name__ == "__main__":
n=86966590627372918010571457840724456774194080910694231109811773050866217415975647358784246153710824794652840306389428729923771431340699346354646708396564203957270393882105042714920060055401541794748437242707186192941546185666953574082803056612193004258064074902605834799171191314001030749992715155125694272289
e=46867417013414476511855705167486515292101865210840925173161828985833867821644239088991107524584028941183216735115986313719966458608881689802377181633111389920813814350964315420422257050287517851213109465823444767895817372377616723406116946259672358254060231210263961445286931270444042869857616609048537240249
d=hack_RSA(e,n)
print(d)
c=37625098109081701774571613785279343908814425141123915351527903477451570893536663171806089364574293449414561630485312247061686191366669404389142347972565020570877175992098033759403318443705791866939363061966538210758611679849037990315161035649389943256526167843576617469134413191950908582922902210791377220066
m=pow(c,d,n)
print(m)
flag=long_to_bytes(m)
print(flag)
注意要装库:pip install pycryptodome,并且将其中的n,e,c改为题目中的。