这里发两题密码,具体全部可以参考CSDN~
给定的加密公式是:
利用二项式定理,( g ) 的幂可以展开为:
exp:
import gmpy2
n = 46196962498972200877758855796872924749844819186626267986927999914182846501730972721014969969101028180625069444974916707989493549745289482550182810861083804677086083424474633448338430837207988351317047771850002977958285942909458579486110472678901311489011660668018040529894352263005948429503462851895869692483
c = 561112313847591646210432155974924416554516215722699464136024810057930163709979335167588946307305023717611789224251564456129337252445423681235116520510753838599006302408405973785072436615253594911056897556016561298642511653370651170814854004436130539049536612507887036508496475200608417744704336863238099651023048528401510071460441511916555279099900129011771281691800420826172236841768991140085782960278815819538210341535165771116022539236882409010456161955143511760480090358241369289697119073668844993429339297945407929761274315997729564517684810244024606264629730413911803767301739399199070960364496887440190129883
# yufu 分解n
p = 6796834741184472912192350855742263953393867402035977259907028842736195216387952144322994792123309530801862588918154635235208755535590050434483745133551473
q = 6796834741184472912192350855742263953393867402035977259907028842736195216387952144322994792123309530801862588918154635235208755535590050434483745133552371
# 已知参数
n = p * q
phi_n = (p-1) * (q-1)
c_phi = pow(c, phi_n, n*n)
# 从c中消除r的影响,并求解m
m_times_phi = (c_phi - 1) // n
m = (m_times_phi * gmpy2.invert(phi_n, n)) % n
# 将数字转换回明文
m_bytes = gmpy2.to_bytes(m)
print(m_bytes.decode())
# flag{1c1e584e1d2a1acc01d791d49db776dd}
素数 q 是通过对 p 异或一个特定值(即 1<<1024 - 1,所有位均为1的1024位数)后再取下一个素数生成的。这个操作实际上意味着 q 和 p 在二进制表示上高位几乎相反。
因为 p 和 q 生成时用到了 1<<1024 - 1,我们可以推断 p + q 接近 1<<1024。使用已知的 n,用 n = pq 来推断 p 和 q 的值。可以用平方差公式推导出 p:
由于只给出了近似值, 需要sympy.nextprime进行微调和验证,直到找到一个能整除 n 的 p
exp:
from Crypto.Util.number import *
import gmpy2
import sympy
n = 5301397598972247313288332496850350716475485201818176955980458785089381574707191944210831459471919268438547016348517878358341850949122832113070247666993006831115364157417862077449453871831496138911957539167293062864005991063696506379253018606534889826983926875281844458278449190215690887758990065486680816431850022695167802229820332079535914813299959461500637336404925209325721343283089517761175011779007681851011863336544965183375219315895402677151071508014559155505903769839446062037040053310622160951350294055710901827003095846137713980848067052032823563903878691757143326022681734259282855347145001850989000828133
c = 1079288169014101061321928206355744925300551220969419075641876262832726487371819994124377608732112547670099114798464745107564003379099865464351619430318916570130366696160364613680416188212506373427854192842804149927749326167345000668560759743411422188762280329222458147559243918808548354718982167094307668515490808028452844301339928770240602408940910104884669929203404701141421299411411547161351395152357207772777307588700851461027931764790951229634521962317240153809080025163705506953575215528712852173457740427501614871042355672720961319392637949157078224852976478262095339770667897824328595526557318622869976192919
e = 65537
# 计算 p 的近似值
p_approx = (gmpy2.iroot(pow(2, 2048) - 4*n, 2)[0] + pow(2, 1024)) // 2
p = int(p_approx)
# 验证并修正 p
while True:
p = sympy.nextprime(p)
if n % p == 0:
print("Found p:", p)
break
# 计算 q
q = n // p
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi)
# 解密 m
m = pow(c, d, n)
flag = long_to_bytes(int(m))
print(flag)
# flag{54b7c69e081e6e0533da6142c234390f}
点分享
点收藏
点在看
原文始发于微信公众号(鱼影安全):2024第八届全国职工职业技能大赛“网络与信息安全管理员”河北省预选拔赛crypto解析
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论