zoukankan      html  css  js  c++  java
  • Buuctf Crypto 刷题记录

    Buuctf Crypto 刷题记录

    写在前面

    • 实习入职,要求继续做比赛crypto方向赛题,由于长时间未接触了,所以现在不得不好好复习一下

    [V&N2020 公开赛]easy_RSA

    考点

    • 平滑大素数分解:使用primefac库可以选取威尔逊定理分解
    • rabbin算法
    • legendre算法
    • tonelli算法

    分析

    def getprime(bits):
        while 1:
            n = 1
            while n.bit_length() < bits:
                n *= next_prime(randint(1,1000))
            if isPrime(n - 1):
                return n - 1
    
    • “题如其名”,真是够easy
    • 先看素数生成部分函数定义,大素数n是由较小的素数进行连乘后减一所得,这个处理方式和之前有一道用到Williams’p+1 algorithm的题目很相似,这次在参考网上的wp时发现了可以直接调用库分解,这给我们这种数学菜鸡终于有了一条活路
    • 首先使用primefac库选择Williams’p+1 algorithm分解,命令如下:
    python -m primefac -vs -m=p+1 7941371739956577280160664419383740967516918938781306610817149744988379280561359039016508679365806108722198157199058807892703837558280678711420411242914059658055366348123106473335186505617418956630780649894945233345985279471106888635177256011468979083320605103256178446993230320443790240285158260236926519042413378204298514714890725325831769281505530787739922007367026883959544239568886349070557272869042275528961483412544495589811933856131557221673534170105409
    参数详解:
    -m : python使用命令行直接执行模块参数
    -vs : 可选参数 [ -v | --verbose ]  [ -s | --summary ] ,-v和-s标志可被组合成以任何顺序单个标志
    -m=p+1 : 选用威尔逊定理 -m =标志控,期间使用的功能多因素相。选项分别是prb,p-1,p + 1,ecm和mpqs,分别表示Pollard的rho,Pollard的p -1,Williams的p +1,椭圆曲线法和多项式二次筛。
    详细用法见:https://pypi.org/project/primefac/
    
    • d = invert(q ** 2, p ** 2)
    • 这里解出p之后,可以就可以根据给出的d,直接求逆算出q,但由于q>p的所以应是还要加上p的倍数
    q2=gmpy2.invert(d,p**2)
    
    for i in range(10000):
        q=gmpy2.iroot(q2+i*p**2,2)
        if(q[1]==1): # iroot()返回的是一个tuple,(mpz(xxx),true),若能开方出来则会返回true
            print(q[0],i)
            break
    q=q[0]
    
    • 对于r直接用n除一下就行了
    • 至此所有参数都可以获得了,再看flag的加密方式可以发现是先有加密生成参数c,而后再由c加密生成给出的密文chiper
    • 这里先解决ccrsa加密形成给出的chiper,这里直接用正常的rsa思路算出c就行
    phi = (p-1)*(q-1)*(r-1)
    
    d1=gmpy2.invert(e,phi)
    
    c1 = pow(chiper,d1,n)
    
    • 三数连乘的欧拉函数,参考nsctf-2019-techworldϕ(p*q*r)=ϕ(N)=ϕ(q)*ϕ(p)*ϕ(r)=(p−1)*(q−1)*(r−1)即可
    • 算出c1之后即可根据托内利-克斯算法:用于解决合数模问题 即r ** 2 = n mod p => pow(r,2,p)还原出flag
    • 算法参考
      https://blog.csdn.net/weixin_44617902/article/details/112785051
    • 完整代码
    # coding:utf-8
    from gmpy2 import *
    from Crypto.Util.number import long_to_bytes'
    
    p=102634610559478918970860957918259981057327949366949344137104804864768237961662136189827166317524151288799657758536256924609797810164397005081733039415393
    n=7941371739956577280160664419383740967516918938781306610817149744988379280561359039016508679365806108722198157199058807892703837558280678711420411242914059658055366348123106473335186505617418956630780649894945233345985279471106888635177256011468979083320605103256178446993230320443790240285158260236926519042413378204298514714890725325831769281505530787739922007367026883959544239568886349070557272869042275528961483412544495589811933856131557221673534170105409
    e = 0x10001
    d=7515987842794170949444517202158067021118454558360145030399453487603693522695746732547224100845570119375977629070702308991221388721952258969752305904378724402002545947182529859604584400048983091861594720299791743887521228492714135449584003054386457751933095902983841246048952155097668245322664318518861440
    chiper=1618155233923718966393124032999431934705026408748451436388483012584983753140040289666712916510617403356206112730613485227084128314043665913357106301736817062412927135716281544348612150328867226515184078966397180771624148797528036548243343316501503364783092550480439749404301122277056732857399413805293899249313045684662146333448668209567898831091274930053147799756622844119463942087160062353526056879436998061803187343431081504474584816590199768034450005448200
    
    q2=invert(d,p**2)
    
    for i in range(10000):
        q=iroot(q2+i*p**2,2)
        if(q[1]==1): # iroot()返回的是一个tuple,(mpz(xxx),true),若能开方出来则会返回true
            print(q[0],i)
            break
    q=q[0]
    r=n//p//q
    
    phi = (p-1)*(q-1)*(r-1)
    
    d1=invert(e,phi)
    
    c1 = pow(chiper,d1,n)
    
    def legendre(a, p): # 勒让德符号 a ** ((p-1)//2) mod p ,解决平方剩余问题
        return pow(a, (p - 1) // 2, p)
    
    
    def tonelli(n, p): # 托内利-克斯算法:用于解决合数模问题 即r ** 2 = n mod p => pow(r,2,p)
        assert legendre(n, p) == 1
        q = p - 1
        s = 0
        while q % 2 == 0:
            q //= 2
            s += 1
        if s == 1:
            return pow(n, (p + 1) // 4, p)
        for z in range(2, 10000):
    #    for z in range(2, p):
            if p - 1 == legendre(z, p):
                break
        c = pow(z, q, p)
        r = pow(n, (q + 1) // 2, p)
        t = pow(n, q, p)
        m = s
        t2 = 0
        while (t - 1) % p != 0:
            t2 = (t * t) % p
            for i in range(1, m):
                if (t2 - 1) % p == 0:
                    break
                t2 = (t2 * t2) % p
            b = pow(c, 1 << (m - i - 1), p)
            r = (r * b) % p
            c = (b * b) % p
            t = (t * c) % p
            m = i
        return r
    
    m = tonelli(c1,r)
    
    print(''.join(long_to_bytes(m)))
    

    [GKCTF2020]babycrypto

    考点

    • Factoring with high bits known Attack

    分析

    • 密文除了p给出的方式有些奇怪,其余的都比较正常,百度直接搜,发现是已知高位攻击,根据https://github.com/Zui-Qing-Feng/RSA/blob/master/03.Factoring%20with%20high%20bits%20known%20Attack修改位数为128即可解出p
    sage:n=0xb119849bc4523e49c6c038a509a74cda628d4ca0e4d0f28e677d57f3c3c7d0d876ef07d7581fe05a060546fedd7d061d3bc70d679b6c5dd9bc66c5bdad8f2ef898b1e785496c4989daf716a1c89d5c174da494eee7061bcb6d52cafa337fc2a7bba42c918bbd3104dff62ecc9d3704a455a6ce282de0d8129e26c840734ffd302bec5f0a66e0e6d00b5c50fa57c546cff9d7e6a978db77997082b4cb927df9847dfffef55138cb946c62c9f09b968033745b5b6868338c64819a8e92a827265f9abd409359a9471d8c3a2631b80e5b462ba42336717700998ff38536c2436e24ac19228cd2d7a909ead1a8494ff6c3a7151e888e115b68cc6a7a8c6cf8a6c005L
    sage:p_fake=0xe4e4b390c1d201dae2c00a4669c0865cc5767bc444f5d310f3cfc75872d96feb89e556972c99ae20753e3314240a52df5dccd076a47c6b5d11b531b92d901b2b512aeb0b263bbfd624fe3d52e5e238beeb581ebe012b2f176a4ffd1e0d2aa8c4d3a2656573b727d4d3136513a931428b00000000000000000000000000000000L
    sage: pbits=1024
    sage: kbits=128
    sage: pbar=p_fake & (2^pbits-2^kbits)
    sage: print("upper %d bits (of %d bits) is given" % (pbits-kbits,pbits))
    upper 896 bits (of 1024 bits) is given
    sage: PR.<x> = PolynomialRing(Zmod(n))
    sage: f=x+pbar
    sage: x0=f.small_roots(X=2^kbits,beta=0.4)[0]
    sage: print(hex(int(x0+pbar)))
    0xe4e4b390c1d201dae2c00a4669c0865cc5767bc444f5d310f3cfc75872d96feb89e556972c99ae20753e3314240a52df5dccd076a47c6b5d11b531b92d901b2b512aeb0b263bbfd624fe3d52e5e238beeb581ebe012b2f176a4ffd1e0d2aa8c4d3a2656573b727d4d3136513a931428b92826225b6d0e735440b613a8336ffa3L
    
    • 解出p剩下就是常规rsa
    import gmpy2
    from Crypto.Util.number import *
    p1=160734387026849747944319274262095716650717626398118440194223452208652532694713113062084219512359968722796763029072117463281356654614167941930993838521563406258263299846297499190884495560744873319814150988520868951045961906000066805136724505347218275230562125457122462589771119429631727404626489634314291445667L
    p2=0xe4e4b390c1d201dae2c00a4669c0865cc5767bc444f5d310f3cfc75872d96feb89e556972c99ae20753e3314240a52df5dccd076a47c6b5d11b531b92d901b2b512aeb0b263bbfd624fe3d52e5e238beeb581ebe012b2f176a4ffd1e0d2aa8c4d3a2656573b727d4d3136513a931428b92826225b6d0e735440b613a8336ffa3
    n2=0xb119849bc4523e49c6c038a509a74cda628d4ca0e4d0f28e677d57f3c3c7d0d876ef07d7581fe05a060546fedd7d061d3bc70d679b6c5dd9bc66c5bdad8f2ef898b1e785496c4989daf716a1c89d5c174da494eee7061bcb6d52cafa337fc2a7bba42c918bbd3104dff62ecc9d3704a455a6ce282de0d8129e26c840734ffd302bec5f0a66e0e6d00b5c50fa57c546cff9d7e6a978db77997082b4cb927df9847dfffef55138cb946c62c9f09b968033745b5b6868338c64819a8e92a827265f9abd409359a9471d8c3a2631b80e5b462ba42336717700998ff38536c2436e24ac19228cd2d7a909ead1a8494ff6c3a7151e888e115b68cc6a7a8c6cf8a6c005L
    e=65537
    q2=n2//p2
    d=gmpy2.invert(e,(p2-1)*(q2-1))
    m2=pow(c,d,n)
    print(long_to_bytes(m2))
    

    [GKCTF2020]Backdoor

    考点

    • rsa公玥文件
    • base64加密

    分析

    • 给出三个文件,一个flag密文,一个公玥文件,源码
    • 常规题,直接用openssl提取ne
      openssl rsa -pubin -text -modulus -in warmip -in pub.pem
    RSA Public-Key: (443 bit)
    Modulus:
        05:77:47:96:b3:01:e1:c7:f4:0b:49:45:05:68:8b:
        1f:de:21:f6:d5:ff:ce:63:6f:f1:67:d8:5e:37:d7:
        a7:b7:49:3e:33:c1:7d:44:17:a2:5c:a2:4a:67:16:
        31:4c:f1:86:e1:69:96:dc:fc:67:9b
    Exponent: 65537 (0x10001)
    Modulus=5774796B301E1C7F40B494505688B1FDE21F6D5FFCE636FF167D85E37D7A7B7493E33C17D4417A25CA24A6716314CF186E16996DCFC679B
    writing RSA key
    -----BEGIN PUBLIC KEY-----
    MFMwDQYJKoZIhvcNAQEBBQADQgAwPwI4BXdHlrMB4cf0C0lFBWiLH94h9tX/zmNv
    8WfYXjfXp7dJPjPBfUQXolyiSmcWMUzxhuFpltz8Z5sCAwEAAQ==
    -----END PUBLIC KEY-----
    
    • Modulus即为n,e直接可以读出
    n=5774796B301E1C7F40B494505688B1FDE21F6D5FFCE636FF167D85E37D7A7B7493E33C17D4417A25CA24A6716314CF186E16996DCFC679B
    e=65537
    
    • n比较小直接分解即可,剩下来就是常规rsa
    import gmpy2
    from Crypto.Util.number import *
    n=15518961041625074876182404585394098781487141059285455927024321276783831122168745076359780343078011216480587575072479784829258678691739L
    p=3386619977051114637303328519173627165817832179845212640767197001941
    q=4582433561127855310805294456657993281782662645116543024537051682479
    c=5902102609936183530036413041949205016072856184947596155784933422689438216690059498706287388882989673839294236821030261398121787376802
    e=65537
    d=gmpy2.invert(e,(p-1)*(q-1))
    m=pow(c,d,n)
    print(long_to_bytes(m))
    
  • 相关阅读:
    centos7.6 安装与配置 MongoDB yum方式
    MongoDB 介绍
    centos 关闭selinux
    前端 HTML标签属性
    前端 HTML 标签嵌套规则
    前端 HTML 标签分类
    前端 HTML body标签相关内容 常用标签 表单标签 form里面的 input标签介绍
    前端 HTML body标签相关内容 常用标签 表单标签 form 表单控件分类
    前端 HTML form表单标签 select标签 option 下拉框
    POJ 1426
  • 原文地址:https://www.cnblogs.com/Konmu/p/14589379.html
Copyright © 2011-2022 走看看