the_easiest_RSA

写在最最最开头!!感谢Xenny,真的太强了。

强到离谱的社区群:941849249

可以变强的提升平台:https://www.ctfer.vip/

the_easiest_RSA


一、关键代码

# 解题最后一步
p = getPrime(512)
q = getPrime(512)
r = getPrime(512)
N = p*p*p*q*q*r
E = random.getrandbits(3) * N
assert E != 0
c = gmpy2.powmod(flag, E, N)
print(c)
print(N)
# hint 求p
e = 65537
P = getPrime(512)
Q = getPrime(512)

hint = pow(p, e, P*Q)

print(hint)
print(P*Q)
print((P >> 128) << 128)
# 提示2 求r
d = getPrime(random.randint(300, 400))
for _ in range(3):
    p = getPrime(512)
    q = getPrime(512)
    e = inverse(d, (p-1)*(q-1))
    print(e)
    print(p*q)
    print(gmpy2.powmod(r, e, p*q))

二、求p

题目过滤掉了P的低128位,利用sage脚本还原P

# sage已知高位

n = 129598944864570286711257254190688970116061394945902262132637837607155691534901891874898804628551250475809878184980250423116425629504829218758694159097845195849688057501913130236213551965850401688761660210649412509677916025475768279720856263985963483363054912938167263889108321013097060701261847903023751603783
# 已知高位但低位未知所以用0代替的p
p_fake = 9668921579171597585499447713067041809069631091614339848644986390369689049549311953755504257359033378043919414270533815757770616304600284932131446188933120
# p的总位数(包括0)
pbits = 512
# p的低位0的位数
kbits = 128
# 取出p_fake的高有效数据位 (pbits-kbits)
pbar = p_fake & (2^pbits-2^kbits)
print("upper %d bits (of %d bits) is given" % (pbits-kbits, pbits))

# 生成一个以x为符号的一元多项式环
PR.<x> = PolynomialRing(Zmod(n))
# 定义求解的函数
f = x + pbar
# 多项式小值根求解及因子分解,X表示求解根的上界
x0 = f.small_roots(X=2^kbits, beta=0.4)[0]  # find root < 2^kbits with factor >= n^0.4
print("p =", x0 + pbar)
# sage output:
# upper 896 bits (of 1024 bits) is given
# p = 9668921579171597585499447713067041809069631091614339848644986390369689049549311953755504257359033378043919414270534152167383591216019342887762779500767333

有了P然后求D,进一步解得最终的p

N = 129598944864570286711257254190688970116061394945902262132637837607155691534901891874898804628551250475809878184980250423116425629504829218758694159097845195849688057501913130236213551965850401688761660210649412509677916025475768279720856263985963483363054912938167263889108321013097060701261847903023751603783
P = 9668921579171597585499447713067041809069631091614339848644986390369689049549311953755504257359033378043919414270534152167383591216019342887762779500767333
Q = N // P
print(isPrime(Q),isPrime(P))
print(N==Q*P)
pi = (P-1)*(Q-1)
E = 65537
D = inverse(E,pi)
hint = 16878097429245530783722133903335212997338285713528713518214728003109174057419513597435122346281201284646480963258130374854750513855615182217644866872008113132819712534581407200402921675953522872066521179022899208737556113901714813515435317960410119875807051040562903175897676599310066517576035935453343096176
p = pow(hint,D,N)
print('p={}'.format(p))
# p=9311389858490364943720442507785055171284652087229819685825097201889131032147259180480486964464071289391134460834678366517191750266970473336556845313099299

三、求r

题目给出3组e、n、c,使用同一个解密指数d,可以利用共解密指数攻击

"""
	instance: 共私钥的RSA实例,为一个列表。该列表的每一项都是字典,instance[i]['e']为第i个RSA实例的e,instance[i]['n']为第i个RSA实例的n。
"""
def common_private_attack(instance, debug=False, algo="LLL"):
    r = len(instance)
    instance.sort(key=lambda x: x['n'])
    M = isqrt(instance[r-1]['n'])  
    
    # Build up Lattice basis B
    B = zero_matrix(r+1)
    B[0,0] = isqrt(instance[r-1]['n'])
    for i in range(1, r+1):
        B[0,i] = instance[i-1]['e']
        B[i,i] = - instance[i-1]['n']
    if debug:
        print("The basis of the lattice we build is:"); print(B)
    
    if algo == "LLL":
        print("Performing LLL reduction..."); B = B.LLL(); print("Done.")
    elif algo == "BKZ":
        print("Performing BKZ reduction..."); B = B.BKZ(block_size=len(instance)); print("Done.")
    
    dM = B[0,0]; d = dM // M;
    # 有时会算出负数
    d = abs(d)
    print(" dM = {} \n d = {}".format(dM, d))

    if dM % d != 0:
        print("Fail to attack these instances.")
dis = [{'e':62107649509595242260985498327362230941626733067909292964711077861884146968524393764549978678481337866348155507716861513326215214728666866477949784023770316976362154222660504811750477838578740521375720597325282479620370158522735575267677677627701353953212156190034408849328503959153342762221926374264053027651,'n':67579813462861282603878327365415253479748370444280113659516130158257373144865467721142569985644927503038822420065524866315225928246828792249490533229575947082470389136063299556830923056174751579905301516931214272550115993594315842786096430348075897579116823654287501623490668169368021982112903184521155573913},
       {'e':91192552959561428901656549453218797211868769229233439570717955188623406593563432307707960017979715994917565882187916480701764277374291128398193565958202598121995066809779140100094491765621015244861869229514784953473829213702003938343693811097627126522188939960339060256479815744446331158926365400274238028803,'n':145976333950451146706634444715893701001415694969457685717184514123014409796207997822737095943734058825931815179434454452685649437531207567414124727379200649895041575542203007316327684029138254183417139206402982005390406598463240894803145304868204357139854460643072986259403556166319722155275780519872827754001},
       {'e':4348966282620964954863899244212242209662910510540204052319150144997303917002071013261204634030736441865929558840715828654566490722583303627043645709981719634890521886934419212195617473300525466133160115932823693249802971146445286315031167637623058158377524494603782928165138698101778238053574351792657563451,'n':114384787632841079048253220979777713739378268018153910083526618289368903392067250680542910855256598382688914805519303106227087573050573700914832336749171834216673179324531933347009364551694605224494508471020884280687659081308509494051018386566231526806905131686822699316935571781598420232882825708380668614959}
      ]
common_private_attack(dis)
# d=1716416079241233716625248301516952595875940503559090013896892408818970255922223460792344537064305948164590602452651

有了d,随便找一组就可解出r,两组同时解验证。

n1 = 67579813462861282603878327365415253479748370444280113659516130158257373144865467721142569985644927503038822420065524866315225928246828792249490533229575947082470389136063299556830923056174751579905301516931214272550115993594315842786096430348075897579116823654287501623490668169368021982112903184521155573913
n2 = 145976333950451146706634444715893701001415694969457685717184514123014409796207997822737095943734058825931815179434454452685649437531207567414124727379200649895041575542203007316327684029138254183417139206402982005390406598463240894803145304868204357139854460643072986259403556166319722155275780519872827754001


c1 = 44895788412038052695271062935700716710096003298843992074268472656998545241926732108950821556069616732076856678399420376306910893249787211937079298205642283799656520246258313504817817458304786535103541978444946220878715540007449758361747501173764050786368425155938627897404095196249573688998161424566538215211
c2 = 118646230308595736293557458002246449715272997471287476720892059140635772575366965589594008104571451357876148349049494917497089671954768795248628188373157874503999033641380460371296189332326326200325179238137611884575706925732632477362082825468087511470153618687379759876359719277900240063537113215552047135841



d = 1716416079241233716625248301516952595875940503559090013896892408818970255922223460792344537064305948164590602452651
m1 = pow(c1,d,n1)
m2 = pow(c2,d,n2)
if m1==m2:
    print('r={}'.format(m1))
else:
    print('NO')

# r=7574044323095532570708874898079912819078129425978705352911750180288319220089479831579074114970296032516798538410455385107525890661740100367688530443421677

四、求q

利用题目已知条件N =p*p*p*q*q*r,解得q

n=821637946044802094902953070074543102306869884873579423162145698218212560752410698552506108846314463135908371234866705393800979683814845596389525129326843295858831422249359573708068647304839244720782685985712635619803869885580152819572638671856305962843339690425926129690760888646694946355455239998544856723512643532949252060312278317964664482052587982507958159258844472388626094774180039916713900974760162202618717715095611085672884887397115862509389558231090407267917488769658024219676982762849860539850223529342350530344977168605879645515110890101177408181561604973969678649331052536135175711781614723243018625804914041552004680786359005886756891564089784004207698042480302197023219264076080698310436288830578669279862026461034180820755901345813488788532773026518857742317030969388255891451584375641479739761793484573965281435630150744924011181628797817182465011004325359576146400420432678566110402359833633223404347714023

q = gmpy2.iroot(n//p//p//p//r,2)[0]
print('q={}'.format(q))
# q=11591898166184703407170679039468830396172686422497264355129193372385309176446185445291532443964976728310025509569413731127733013564906117798148077662926901

五、求解flag

归整求得结果,求解flag

p=9311389858490364943720442507785055171284652087229819685825097201889131032147259180480486964464071289391134460834678366517191750266970473336556845313099299
q=11591898166184703407170679039468830396172686422497264355129193372385309176446185445291532443964976728310025509569413731127733013564906117798148077662926901
r=7574044323095532570708874898079912819078129425978705352911750180288319220089479831579074114970296032516798538410455385107525890661740100367688530443421677
c = 254405107303005845049072747258149485455665434531849341949389151702896351704377285067476806399735915847551051984934926645265066676195182212668342809240170275111601925685425108739633735306028738440813976431594863569098420495195211247259496523691182750966814434291138671594822376699489067358139495566395880145059037908529964205911131567968259107857590036018068978645060903255984751462867095474972084318246942230515795372922732450012495738566643657477922873319803490046893484493433788181603654210794341892738158118219924980457355211094042834795257379632330516037706451375827720587904837405865838650441538283621256535491641274818330647441525602168055479178687963531914961778234475318884588150397234095722213462400828744953497197126537474009027706337497767417837993861139340860874583027430907228716660953102425009174890588920766879848601641875277580421221804043645286722094547226197336752873572741091909840169196029400597100303993
n = p*p*p*q*q*r
# phi =(p*p*(q-1))*(p*(p-1))*(r-1) 无逆元

# 可以换成phi(p*q*r)和n的逆元,那么他们就在模p*q*r下成立

phi_qpr = (p-1)*(q-1)*(r-1)
d= inverse(n,phi_qpr)

for i in range(1,8,1):
    m = pow(c,d,q*p*r)
    flag = long_to_bytes(gmpy2.iroot(m,i)[0])
    if b'flag' in flag:
        print(flag.decode())
# flag{th1s-i5-7he-fla9}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值