zoukankan      html  css  js  c++  java
  • HITCON 2019 Lost Modular again writeup

    HITCON 2019 Lost Modular again writeup

    算是基础题,有很多之前题的影子,做不出来纯属菜。

    题目

    • 加密脚本
    from Crypto.Util.number import *
    
    class Key:
        def __init__(self, bits):
            assert bits >= 512
            self.p = getPrime(bits)
            self.q = getPrime(bits)
            self.n = self.p * self.q
            self.e = 0x100007
            self.d = inverse(self.e, (self.p-1)*(self.q-1))
            self.dmp1 = self.d%(self.p-1)
            self.dmq1 = self.d%(self.q-1)
            self.iqmp = inverse(self.q, self.p)
            self.ipmq = inverse(self.p, self.q)
    
        def encrypt(self, data):
            num = bytes_to_long(data)
            result = pow(num, self.e, self.n)
            return long_to_bytes(result)
    
        def decrypt(self, data):
            num = bytes_to_long(data)
            v1 = pow(num, self.dmp1, self.p)
            v2 = pow(num, self.dmq1, self.q)
            result = (v2*self.p*self.ipmq+v1*self.q*self.iqmp) % self.n
            return long_to_bytes(result)
    
        def __str__(self):
            return "Key([e = {0}, n = {1}, x = {2}, y = {3}])".format(self.e, self.d, self.iqmp, self.ipmq)
    
    def main():
        key = Key(1024)
        flag = open('flag').read()
        encrypt_flag = key.encrypt(flag)
        assert key.decrypt(encrypt_flag) == flag
        print key
        print encrypt_flag.encode('hex')
    
    if __name__ == '__main__':
        main()
    
    • 输出
    Key([e = 1048583, n = 20899585599499852848600179189763086698516108548228367107221738096450499101070075492197700491683249172909869748620431162381087017866603003080844372390109407618883775889949113518883655204495367156356586733638609604914325927159037673858380872827051492954190012228501796895529660404878822550757780926433386946425164501187561418082866346427628551763297010068329425460680225523270632454412376673863754258135691783420342075219153761633410012733450586771838248239221434791288928709490210661095249658730871114233033907339401132548352479119599592161475582267434069666373923164546185334225821332964035123667137917080001159691927, x = 22886390627173202444468626406642274959028635116543626995297684671305848436910064602418012808595951325519844918478912090039470530649857775854959462500919029371215000179065185673136642143061689849338228110909931445119687113803523924040922470616407096745128917352037282612768345609735657018628096338779732460743, y = 138356012157150927033117814862941924437637775040379746970778376921933744927520585574595823734209547857047013402623714044512594300691782086053475259157899010363944831564630625623351267412232071416191142966170634950729938561841853176635423819365023039470901382901261884795304947251115006930995163847675576699331])
    32074de818f2feeb788e36d7d3ee09f0000381584a72b2fba0dcc9a2ebe5fd79cf2d6fd40c4dbfea27d3489704f2c1a30b17a783baa67229d02043c5bc9bdb995ae984d80a96bd79370ea2c356f39f85a12d16983598c1fb772f9183441fea5dfeb5b26455df75de18ce70a6a9e9dbc0a4ca434ba94cf4d1e5347395cf7aafa756c8a5bd6fd166bc30245a4bded28f5baac38d024042a166369f7515e8b0c479a1965b5988b350064648738f6585c0a0d1463bd536d11a105bb926b44236593b5c6c71ef5b132cd9c211e8ad9131aa53ffde88f5b0df18e7c45bcdb6244edcaa8d386196d25297c259fca3be37f0f2015f40cb5423a918c51383390dfd5a8703
    

    初步分析

    题目给定了e,d,x,y,(x = q^{-1} mod p,y = p^{-1} mod q)(代码命名混乱)。

    根据rsa的原理,(ed == 1 mod phi(n)),故(e*d-1)一定是(phi(n))的倍数,即(e*d-1==k*phi(n))(k)是整数,由于(d<n)(k<e)(e)的值不是很大,通过枚举可以确定所有(k)的可能值,代入(e*d-1==k*phi(n)=k*(p-1)*(q-1)),得到关于(p,q)的方程。凭借直觉,通过(x,y)肯定能确定另外一个方程,最后解出(p,q)

    另一个方程的推导

    [xq = 1 + w_1*p,yp = 1 + w_2*q ]

    [xq-1 = w_1*p,yp-1 = w_2*q ]

    我们的目的是得到(p,q)的数量关系,势必要去掉(w_1,w_2)。所以两边相乘(xypq-xq-yp+1=w_1w_2pq)(xq+yp-1= (xy-w_1w_2)*pq)。这里我们知道(x<p,y<q)。所以(0<(xy-w_1w_2)*pq<2*pq)。这样我们就知道了其实(xy-w_1w_2=1)。这样我们又得到了一个关于(p,q)的等式。通过两个方程联立,最终可以解出(p,q)的值。

    解决脚本

    依赖

    • pycryptodome
    • tqdm
    • gmpy2
    from Crypto.Util.number import long_to_bytes
    from tqdm import trange
    import gmpy2,binascii
    
    d = 20899585599499852848600179189763086698516108548228367107221738096450499101070075492197700491683249172909869748620431162381087017866603003080844372390109407618883775889949113518883655204495367156356586733638609604914325927159037673858380872827051492954190012228501796895529660404878822550757780926433386946425164501187561418082866346427628551763297010068329425460680225523270632454412376673863754258135691783420342075219153761633410012733450586771838248239221434791288928709490210661095249658730871114233033907339401132548352479119599592161475582267434069666373923164546185334225821332964035123667137917080001159691927
    x = 22886390627173202444468626406642274959028635116543626995297684671305848436910064602418012808595951325519844918478912090039470530649857775854959462500919029371215000179065185673136642143061689849338228110909931445119687113803523924040922470616407096745128917352037282612768345609735657018628096338779732460743
    y = 138356012157150927033117814862941924437637775040379746970778376921933744927520585574595823734209547857047013402623714044512594300691782086053475259157899010363944831564630625623351267412232071416191142966170634950729938561841853176635423819365023039470901382901261884795304947251115006930995163847675576699331
    e = 1048583
    
    klist = []
    for i in trange(1,e):
        if (e*d-1)%i==0:
            klist.append(i)
    print(len(klist))
    nlist = []
    for k in klist:
        w = (e*d-1)//k
        a = y-1
        b = x-y-w
        c = 1-x+w*x
        delt = b*b-4*a*c
        if delt<0 :
            continue
        s,t = gmpy2.isqrt_rem(delt)
        if t!=0:
            continue
        if (s-b)%(2*a)!=0:
            continue
        q = (s-b)//(2*a)
        if (w+q-1)%(q-1)!=0:
            continue
        p = (w+q-1)//(q-1)
        n = p*q
        nlist.append(n)
    print(nlist)
    n = 22509077260984027608263845908083202879597081619164800783060781115945741547031252889863077300004310236160814653393991988068104999928735140821504649764471313283345921984799288521496479399032837319974588038186917872597078510975400908137738190304700710900604891709265153418588830065918981914371070605822998222527238465925300150253661563857557769597206945843298561291788401379974127990007737364134474570192828364417568030703631487414510799126846577679080152555651843717973023204220528124089432708534457966658829476472791371567790491496967424845002161008643478300481541860754837427906812836584810660110698219790829058527133
    c = 0x32074de818f2feeb788e36d7d3ee09f0000381584a72b2fba0dcc9a2ebe5fd79cf2d6fd40c4dbfea27d3489704f2c1a30b17a783baa67229d02043c5bc9bdb995ae984d80a96bd79370ea2c356f39f85a12d16983598c1fb772f9183441fea5dfeb5b26455df75de18ce70a6a9e9dbc0a4ca434ba94cf4d1e5347395cf7aafa756c8a5bd6fd166bc30245a4bded28f5baac38d024042a166369f7515e8b0c479a1965b5988b350064648738f6585c0a0d1463bd536d11a105bb926b44236593b5c6c71ef5b132cd9c211e8ad9131aa53ffde88f5b0df18e7c45bcdb6244edcaa8d386196d25297c259fca3be37f0f2015f40cb5423a918c51383390dfd5a8703
    m = gmpy2.powmod(c,d,n)
    print(long_to_bytes(m))
    
  • 相关阅读:
    ES6解构赋值
    ES6中的Symbol类型
    两个列表合并成字典
    python关于列表转为字典的两个小方法
    break、continue和return的使用
    进度条的实现
    md5加密
    dict字典方法
    用户相关的文件、解析以及命令的使用
    linux的根目录
  • 原文地址:https://www.cnblogs.com/zhuowangy2k/p/11758321.html
Copyright © 2011-2022 走看看