
题目:
python
from Crypto.Util.number import *
flag = open('flag.txt', 'rb').read()
m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
e = 65537
n = p * q
c = pow(m, e, n)
s = getPrime(256)
M = getPrime(5048)
hint = (p - 297498275426) * inverse(s, M) % M
t = open("message.txt", "w")
t.write(f"e = {e}\nc = {c}\nn = {n}\nM = {M}\nhint = {hint}\n")
t.close()
python
e = 65537
c = 11223534598141520071392544441952727165225232358333005778273904279807651365082135278999006409297342081157139972503703772556228315654837441044781410960887536342197257046095815516053582104516752168718754752274252871063410625756822861003235434929734796245933907621657696650609132419469456238860601166224944487116
n = 99499509473364452726944770421623721217675378717234178828554602484867641740497277374806036356486848621495917213623425604565104435195783450029879177770305417469850119739921527698744700219067563802483159458398895082044997907953256062342593605652927874232404778144112740505724215742062859322375891810785229735653
M = 28858066896535909755146975040720031655813099454455588895434479778600245612915775220883088811806723015938061791264869678085304248608125313205719043320256733514389739252845381708094678596099621503299764646358765107958130065721737938646850422959290465490270263553423913213684958592738500488797707239673645370968467090153285601432966586133693641854092761919184904521240074718850103356119966387029699913571443658384564840234765103070736676067458391659605655580766436276719610283460962533141261830775028138998594269732067550977245136631815804641115446066102981044849495663224005844657686979516481904043008222498344271373989609634617315702887646444506965035406154183377067490922195507071571055579654138590566650703038341939225657159668601565182939447340585110418258653618384852356058444795156595720943362884361136229430356254095673818462046182310826133487611183265532844700265640889105864909560170846171486510513240630480729194415061752698286990999064594811803482429976978688266632277914610443963726561921790718480343488391563503774868490108659902216386976683532579945706490286814310031310144410303859633785939399012605326754445715302492704458881700872467560968264583996658711892595658439058034434031646411995511168849724976850557976639662545139917517675296224197763447929417263845949813741362574641118781293171167041592771305352186419565096347024619027397784780864922205105185970180629777320680707022011697404359388540366320053501502698747763307336114482530784826238326983596966436776918503653153420281803168537703048371580451
hint = 24302462761412867722556483860201357169283131384498485449193507018526006760633350601593235386242712333885826513399701577522498685938541691414316724804357523659514319083860507720945068584985970098437482386854188516742033184163273293005356970701527614010961471490166306765208284126815267752826036846338185010168551115391901008731195800723630612524215610302192763771954146943262822909368086155537366851998954401585888789660061750804720858175620022924944428882337005545535959410243692854073069775794945154943244522898330286785483043492678802461244624116832548150221211726044545331789932659966539042635768789637635754297830131948383991027466194455817875377950516103513735000718642093769229006510961952865719649517629939801014585849419818774317178973918720330390674833583065434312010539617630210110724391629534996688713945139529416075521015600392479980677759342058040778532467875961508475990300178277703011765698425360329342396347848373844031930655143343217447877587074485794273364964346235973542157189093330870952677683308479410235841331914353677363106473914986073397716367455628483060709281215783434084559550690248426391913205234184130354155776334292729262232484610747771114078013979494659835579574006801652858265173309736540235377076956677464263798132149783780830729103485354096234062135454873557941791812722418582207577124971978987895472250326100927372068822672582017222521124179752698654114839303426099426224351872025466618402675104161895600513776962289703455252021742990686505176582638132300246212598903123706906104217087
题目分析
已知参数:
-
公钥:(e, n) = (65537, 994...)
-
密文:c
-
额外参数:M 和 hint
-
目标:解密得到明文 m
解题思路详解
1. 分析关键参数关系
python
# 给定的参数
e = 65537
n = p * q
M # 一个非常大的数
hint # 另一个大数,与p、s有关
从代码中可以看出:
-
p是素数,且p = p + 297498275426(这说明我们从LLL得到的是p的一部分) -
s是另一个未知数,与hint有关系
2. 格构造分析
python
L = matrix(ZZ,[[1,hint],[0,M]])
构造的格是2×2矩阵:
python
[ 1 hint ]
[ 0 M ]
为什么这样构造?
题目暗示了存在关系:hint ≈ s/p mod M 或类似关系。
实际上,这种构造通常用于解决以下类型的问题:
存在整数 s 和 p,使得:
s + hint * p ≡ 0 mod M
且 s 和 p 都比较小。
3. LLL算法的作用
python
v = L.LLL()
s,p = map(abs,v[0])
LLL算法会找到格中的短向量,这里 v[0] 是找到的最短向量 (s, p)。
数学原理:
-
我们寻找的向量
(s, p)满足:s + hint * p ≡ 0 mod M -
这意味着存在整数 k,使得:
s + hint * p = k * M -
由于 M 非常大,如果 s 和 p 相对较小,那么
(s, p)就是格中的短向量
4. 恢复完整的 p
python
p = p + 297498275426
这说明LLL找到的 p 只是真实p的一部分(低位或高位),需要加上一个固定值才能得到完整的p。
5. 计算私钥并解密
python
q = n // p # 计算另一个素数因子
phi = (p - 1)*(q - 1) # 计算欧拉函数
d = inverse(e, phi) # 计算私钥d
m = long_to_bytes(Integer(pow(c, d, n))) # RSA解密
完整代码
python
from Crypto.Util.number import *
# 题目给定的参数
e = 65537
c = 11223534598141520071392544441952727165225232358333005778273904279807651365082135278999006409297342081157139972503703772556228315654837441044781410960887536342197257046095815516053582104516752168718754752274252871063410625756822861003235434929734796245933907621657696650609132419469456238860601166224944487116
n = 99499509473364452726944770421623721217675378717234178828554602484867641740497277374806036356486848621495917213623425604565104435195783450029879177770305417469850119739921527698744700219067563802483159458398895082044997907953256062342593605652927874232404778144112740505724215742062859322375891810785229735653
M = 28858066896535909755146975040720031655813099454455588895434479778600245612915775220883088811806723015938061791264869678085304248608125313205719043320256733514389739252845381708094678596099621503299764646358765107958130065721737938646850422959290465490270263553423913213684958592738500488797707239673645370968467090153285601432966586133693641854092761919184904521240074718850103356119966387029699913571443658384564840234765103070736676067458391659605655580766436276719610283460962533141261830775028138998594269732067550977245136631815804641115446066102981044849495663224005844657686979516481904043008222498344271373989609634617315702887646444506965035406154183377067490922195507071571055579654138590566650703038341939225657159668601565182939447340585110418258653618384852356058444795156595720943362884361136229430356254095673818462046182310826133487611183265532844700265640889105864909560170846171486510513240630480729194415061752698286990999064594811803482429976978688266632277914610443963726561921790718480343488391563503774868490108659902216386976683532579945706490286814310031310144410303859633785939399012605326754445715302492704458881700872467560968264583996658711892595658439058034434031646411995511168849724976850557976639662545139917517675296224197763447929417263845949813741362574641118781293171167041592771305352186419565096347024619027397784780864922205105185970180629777320680707022011697404359388540366320053501502698747763307336114482530784826238326983596966436776918503653153420281803168537703048371580451
hint = 24302462761412867722556483860201357169283131384498485449193507018526006760633350601593235386242712333885826513399701577522498685938541691414316724804357523659514319083860507720945068584985970098437482386854188516742033184163273293005356970701527614010961471490166306765208284126815267752826036846338185010168551115391901008731195800723630612524215610302192763771954146943262822909368086155537366851998954401585888789660061750804720858175620022924944428882337005545535959410243692854073069775794945154943244522898330286785483043492678802461244624116832548150221211726044545331789932659966539042635768789637635754297830131948383991027466194455817875377950516103513735000718642093769229006510961952865719649517629939801014585849419818774317178973918720330390674833583065434312010539617630210110724391629534996688713945139529416075521015600392479980677759342058040778532467875961508475990300178277703011765698425360329342396347848373844031930655143343217447877587074485794273364964346235973542157189093330870952677683308479410235841331914353677363106473914986073397716367455628483060709281215783434084559550690248426391913205234184130354155776334292729262232484610747771114078013979494659835579574006801652858265173309736540235377076956677464263798132149783780830729103485354096234062135454873557941791812722418582207577124971978987895472250326100927372068822672582017222521124179752698654114839303426099426224351872025466618402675104161895600513776962289703455252021742990686505176582638132300246212598903123706906104217087
# 第一步:构造格进行LLL规约
# 这里利用了hint和M之间的关系:存在小整数s和p使得 s + hint*p ≈ k*M
L = matrix(ZZ, [[1, hint], [0, M]])
v = L.LLL() # LLL算法找到格中的短向量
# 提取短向量,abs确保为正数
s, p = map(abs, v[0])
# 第二步:恢复完整的p
# LLL找到的p只是部分值,需要加上固定偏移量
p = p + 297498275426
# 第三步:计算q并验证
q = n // p
# 验证p*q是否等于n
assert p * q == n, "p和q的乘积不等于n,可能p值不正确"
# 第四步:计算私钥d
phi = (p - 1) * (q - 1) # 欧拉函数
d = inverse(e, phi) # 计算模反元素
# 第五步:解密得到明文
m = long_to_bytes(Integer(pow(c, d, n)))
print("解密得到的明文:")
print(m)
最后flag为
NSSCTF{388bb794-ccda-f02e-79c6-8e44659c2481}
关键点总结
-
格构造技巧 :题目通过
hint和M隐藏了关于p的信息,利用LLL可以恢复出小解 -
部分密钥恢复 :LLL找到的
p只是真实值的一部分,需要加上固定偏移297498275426