ctf-ichunqiu-crypto

1.rsa256

下载文件,解压得到4个文件,打开message后缀文件里面都是乱码。打开public.key,观察其格式明显是openssl的公钥文件,再根据题目提示可知,我们拿到的message后缀文件是由该公钥rsa加密得到的,用openssl命令获取public.key中的n和e,发现n并不是很大,可以用msieve分解得到p,q。这样我们就可已得到d,用n,d对密文解密,将得到的16进制通过ascii转为字符输出(注意里面存在不可输出字符,直接输出有可能截断字符串导致输出不完整)

import sys
import os
import gmpy2
def shuchu(mingwenstr):
    if mingwenstr[len(mingwenstr)-1]=='L':
        mingwenstr=mingwenstr[2:len(mingwenstr)-1]
    else:
        mingwenstr=mingwenstr[2:len(mingwenstr)]
    if not len(mingwenstr)%2==0:
            mingwenstr='0'+mingwenstr
    i=len(mingwenstr)
    mingwen=""
    while i>=1:
        str1=mingwenstr[i-2:i]
        if int(str1,16)>33 and int(str1,16)<126:
            mingwen=chr(int(str1,16))+mingwen
        else :
            mingwen=" "+mingwen
        i=i-2
    print mingwen
p=302825536744096741518546212761194311477
q=325045504186436346209877301320131277983
e=65537
n=p*q
d=int(gmpy2.invert(e,(p-1)*(q-1)))
with open("encrypted.message1" , "rb") as f:
    s=f.read()
    miwen=long(s.encode('hex'),16)
    mingwenint=pow(miwen,d,n)
    mingwenstr=hex(mingwenint)
    shuchu(mingwenstr)
with open("encrypted.message2" , "rb") as f:
    s=f.read()
    miwen=long(s.encode('hex'),16)
    mingwenint=pow(miwen,d,n)
    mingwenstr=hex(mingwenint)
    shuchu(mingwenstr)
with open("encrypted.message3" , "rb") as f:
    s=f.read()
    miwen=long(s.encode('hex'),16)
    mingwenint=pow(miwen,d,n)
    mingwenstr=hex(mingwenint)
    shuchu(mingwenstr)

对结果观察,即可获取明文

2.RSA

打开文件即可看到n,e,c,n比较长,可放入yafu进行分解得到p,q。即可得到d,对c解密输出即可

import gmpy2
def shuchu(mingwenstr):
    if mingwenstr[len(mingwenstr)-1]=='L':
        mingwenstr=mingwenstr[2:len(mingwenstr)-1]
    else:
        mingwenstr=mingwenstr[2:len(mingwenstr)]
    if not len(mingwenstr)%2==0:
            mingwenstr='0'+mingwenstr
    i=len(mingwenstr)
    mingwen=""
    while i>=1:
        str1=mingwenstr[i-2:i]
        if int(str1,16)>33 and int(str1,16)<126:
            mingwen=chr(int(str1,16))+mingwen
        else :
            mingwen=" "+mingwen
        i=i-2
    print mingwen
p=31093551302922880999883020803665536616272147022877428745314830867519351013248914244880101094365815998050115415308439610066700139164376274980650005150267949853671653233491784289493988946869396093730966325659249796545878080119206283512342980854475734097108975670778836003822789405498941374798016753689377992355122774401780930185598458240894362246194248623911382284169677595864501475308194644140602272961699230282993020507668939980205079239221924230430230318076991507619960330144745307022538024878444458717587446601559546292026245318907293584609320115374632235270795633933755350928537598242214216674496409625928997877221
q=31093551302922880999883020803665536616272147022877428745314830867519351013248914244880101094365815998050115415308439610066700139164376274980650005150267949853671653233491784289493988946869396093730966325659249796545878080119206283512342980854475734097108975670778836003822789405498941374798016753689377992355122774401780930185598458240894362246194248623911382284169677595864501475308194644140602272961699230282993020507668939980205079239221924230430230318076991507619960330144745307022538024878444458717587446601559546292026245318907293584609320115374632235270795633933755350928537598242214216674496409625928797450473
e=65537
n=p*q
d=int(gmpy2.invert(e,(p-1)*(q-1)))
c=168502910088858295634315070244377409556567637139736308082186369003227771936407321783557795624279162162305200436446903976385948677897665466290852769877562167487142385308027341639816401055081820497002018908896202860342391029082581621987305533097386652183849657065952062433988387640990383623264405525144003500286531262674315900537001845043225363148359766771033899680111076181672797077410584747509581932045540801777738548872747597899965366950827505529432483779821158152928899947837196391555666165486441878183288008753561108995715961920472927844877569855940505148843530998878113722830427807926679324241141182238903567682042410145345551889442158895157875798990903715105782682083886461661307063583447696168828687126956147955886493383805513557604179029050981678755054945607866353195793654108403939242723861651919152369923904002966873994811826391080318146260416978499377182540684409790357257490816203138499369634490897553227763563553981246891677613446390134477832143175248992161641698011195968792105201847976082322786623390242470226740685822218140263182024226228692159380557661591633072091945077334191987860262448385123599459647228562137369178069072804498049463136233856337817385977990145571042231795332995523988174895432819872832170029690848
mingwenint=pow(c,d,n)
mingwenstr=hex(mingwenint)
shuchu(mingwenstr)

3.RSA?

打开文件发现e=1,有rsa加密原理可知这里大概率m=c,直接将c转为字符获得答案

4.RSA

打开文件发现已知d,那么直接使用密钥解密即可

5.RSA2

和RSA基本一样,打开文件即可看到n,e,c,n比较长,可放入yafu进行分解得到p,q。即可得到d,对c解密输出即可

import gmpy2
def shuchu(mingwenstr):
    if mingwenstr[len(mingwenstr)-1]=='L':
        mingwenstr=mingwenstr[2:len(mingwenstr)-1]
    else:
        mingwenstr=mingwenstr[2:len(mingwenstr)]
    if not len(mingwenstr)%2==0:
            mingwenstr='0'+mingwenstr
    i=len(mingwenstr)
    mingwen=""
    while i>=1:
        str1=mingwenstr[i-2:i]
        if int(str1,16)>33 and int(str1,16)<126:
            mingwen=chr(int(str1,16))+mingwen
        else :
            mingwen=" "+mingwen
        i=i-2
    print mingwen
p=57970027
q=518629368090170828331048663550229634444384299751272939077168648935075604180676006392464524953128293842996441022771890719731811852948684950388211907532651941639114462313594608747413310447500790775078081191686616804987790818396104388332734677935684723647108960882771460341293023764117182393730838418468480006985768382115446225422781116531906323045161803441960506496275763429558238732127362521949515590606221409745127192859630468854653290302491063292735496286233738504010613373838035073995140744724948933839238851600638652315655508861728439180988253324943039367876070687033249730660337593825389358874152757864093
e=65537
n=p*q
d=int(gmpy2.invert(e,(p-1)*(q-1)))
c='0x3dbf00a02f924a70f44bdd69e73c46241e9f036bfa49a0c92659d8eb0fe47e42068eaf156a9b3ee81651bc0576a91ffed48610c158dc8d2fb1719c7242704f0d965f8798304925a322c121904b91e5fc5eb3dc960b03eb8635be53b995217d4c317126e0ec6e9a9acfd5d915265634a22a612de962cfaa2e0443b78bdf841ff901423ef765e3d98b38bcce114fede1f13e223b9bd8155e913c8670d8b85b1f3bcb99353053cdb4aef1bf16fa74fd81e42325209c0953a694636c0ce0a19949f343dc229b2b7d80c3c43ebe80e89cbe3a3f7c867fd7cee06943886b0718a4a3584c9d9f9a66c9de29fda7cfee30ad3db061981855555eeac01940b1924eb4c301'
miwen=int(c,16)
mingwenint=pow(miwen,d,n)
mingwenstr=hex(mingwenint)
shuchu(mingwenstr)

6.medium RSA

下载文件解压得到一个enc文件,一个pem文件,而enc文件并不是数据包文件,用文本文件打开发现乱码,而pem文件时openssl的公钥文件,根据题目可知enc文件时用RSA公钥文件pem加密得到的密钥文件,用openssl获取pem文件中的n,e,发现n不太大,可放入msieve进行分解得到p,q。即可得到d,对enc文件解密输出即可

import sys
import os
import gmpy2
def shuchu(mingwenstr):
    if mingwenstr[len(mingwenstr)-1]=='L':
        mingwenstr=mingwenstr[2:len(mingwenstr)-1]
    else:
        mingwenstr=mingwenstr[2:len(mingwenstr)]
    if not len(mingwenstr)%2==0:
            mingwenstr='0'+mingwenstr
    i=len(mingwenstr)
    mingwen=""
    while i>=1:
        str1=mingwenstr[i-2:i]
        if int(str1,16)>33 and int(str1,16)<126:
            mingwen=chr(int(str1,16))+mingwen
        else :
            mingwen=" "+mingwen
        i=i-2
    print mingwen
p=275127860351348928173285174381581152299
q=319576316814478949870590164193048041239
e=65537
n=p*q
d=int(gmpy2.invert(e,(p-1)*(q-1)))
with open("flag.enc" , "rb") as f:
    s=f.read()
    miwen=long(s.encode('hex'),16)
    mingwenint=pow(miwen,d,n)
    mingwenstr=hex(mingwenint)
    shuchu(mingwenstr)

7.hard RSA

与medium RSA相似,下载文件解压又得到一个enc文件,一个pem文件,且enc文件并不是数据包文件,而pem文件时openssl的公钥文件,根据题目可知enc文件时用RSA公钥文件pem加密得到的密钥文件,用openssl获取pem文件中的n,e,n与medium RSA的n相同,却发现这里的e=2。当e为2时,与n的欧拉函数不再互质,无法求出d,无法再用正常的RSA解密方式来解密。但这里n依旧可以分解为两个素数p,q,且p%4=3,q%4=3,这里我们有Toelli-shanks算法的直接结论使用,对于给定c和p,当p%4=3,当(m^2)=cmodp的解有m=(c^((p+1)/4))modp或m=-(c^((p+1)/4))modp(即m=((c^(1/2))modp)的解),在根据中国剩余定理将模p的解mp和模q的解mq组合为模n的解(这种加解密成为rabin加解密),这里会出现四个解(根据欧几里得扩展原理获得yp*mp+yq*mq=1

r=(yp*p*mq+yq*q*mp)modn

-r=n-r

s=(yp*p*mq-yq*q*mp)modn

-s=n-s

即可得到结果


import gmpy2
import libnum
def shuchu(mingwenstr):
    mingwenstr=mingwenstr[2:len(mingwenstr)-1]
    if not len(mingwenstr)%2==0:
            mingwenstr='0'+mingwenstr
    i=len(mingwenstr)
    mingwen=""
    while i>=1:
        str1=mingwenstr[i-2:i]
        if int(str1,16)>33 and int(str1,16)<126:
            mingwen=chr(int(str1,16))+mingwen
        else :
            mingwen=" "+mingwen
        i=i-2
    print mingwen

p=275127860351348928173285174381581152299
q=319576316814478949870590164193048041239
n=p*q
f=open("flag.enc","r")
s=f.read()
f.close()
c=long(s.encode('hex'),16)
#获得c^(1/2)modp,q的解
r=pow(c,(p+1)/4,p)
s=pow(c,(q+1)/4,q)
#使用中国定理组合解
pni=int(gmpy2.invert(p,q))
qni=int(gmpy2.invert(q,p))
a=(s*p*pni+r*q*qni)%n
a1=n-a
b=(s*p*pni-r*q*qni)%n
b1=n-b
shuchu(hex(a))
shuchu(hex(a1))
shuchu(hex(b))
shuchu(hex(b1))

8.very hard RSA

下载文件解压又得到两个enc文件,一个py文件,首先打开py文件阅读加密算法,可知这一次是分别使用RSA公钥(N,e1)和(N,e2)对相同密文加密,可以使用RSA共模攻击破解密文

import gmpy2 
#在a,b较小时可用这种欧几里得扩展
def egcd(a, b):
  if a == 0:
    return (b, 0, 1)
  else:
    g, y, x = egcd(b % a, a)
    return (g, x - (b // a) * y, y)
def shuchu(mingwenstr):
    if mingwenstr[len(mingwenstr)-1]=='L':
        mingwenstr=mingwenstr[2:len(mingwenstr)-1]
    else:
        mingwenstr=mingwenstr[2:len(mingwenstr)]
    if not len(mingwenstr)%2==0:
            mingwenstr='0'+mingwenstr
    i=len(mingwenstr)
    mingwen=""
    while i>=1:
        str1=mingwenstr[i-2:i]
        if int(str1,16)>33 and int(str1,16)<126:
            mingwen=chr(int(str1,16))+mingwen
        else :
            mingwen=" "+mingwen
        i=i-2
    print mingwen

n=0x00b0bee5e3e9e5a7e8d00b493355c618fc8c7d7d03b82e409951c182f398dee3104580e7ba70d383ae5311475656e8a964d380cb157f48c951adfa65db0b122ca40e42fa709189b719a4f0d746e2f6069baf11cebd650f14b93c977352fd13b1eea6d6e1da775502abff89d3a8b3615fd0db49b88a976bc20568489284e181f6f11e270891c8ef80017bad238e363039a458470f1749101bc29949d3a4f4038d463938851579c7525a69984f15b5667f34209b70eb261136947fa123e549dfff00601883afd936fe411e006e4e93d1a00b0fea541bbfc8c5186cb6220503a94b2413110d640c77ea54ba3220fc8f4cc6ce77151e29b3e06578c478bd1bebe04589ef9a197f6f806db8b3ecd826cad24f5324ccdec6e8fead2c2150068602c8dcdc59402ccac9424b790048ccdd9327068095efa010b7f196c74ba8c37b128f9e1411751633f78b7b9e56f71f77a1b4daad3fc54b5e7ef935d9a72fb176759765522b4bbc02e314d5c06b64d5054b7b096c601236e6ccf45b5e611c805d335dbab0c35d226cc208d8ce4736ba39a0354426fae006c7fe52d5267dcfb9c3884f51fddfdf4a9794bcfe0e1557113749e6c8ef421dba263aff68739ce00ed80fd0022ef92d3488f76deb62bdef7bea6026f22a1d25aa2a92d124414a8021fe0c174b9803e6bb5fad75e186a946a17280770f1243f4387446ccceb2222a965cc30b3929
e1=17
e2=65537
g,s1,s2=egcd(e1, e2)
fo1 = open('flag.enc1','rb')
fo2 = open('flag.enc2','rb')
data1 = fo1.read()
data2 = fo2.read()
fo1.close()
fo2.close()
c1 = int(data1.encode('hex'),16)
c2 = int(data2.encode('hex'),16)
if s1<0:
    c1=int(gmpy2.invert(c1,n))
    s1=-s1
if s2<0:
    c2=int(gmpy2.invert(c2,n))
    s2=-s2
miwenint=(pow(c1,s1,n)*pow(c2,s2,n))%n
shuchu(hex(miwenint))

9.Round Rabins!

已知此题是rabin解密(在hard RSA已经提到如何解密),发现n较长,放在yafu中分解,结果发现n是一个平方数,这样正常的rabin解密无法解密此题(中国剩余定理要求分解得到的因子互素),此时问题变成了如何求解m=(c^(1/2))%(p^2)(其中n=p^2)。我们可以根据Toelli-shanks算法(在hard RSA已经提到)求出m=(c^(1/2))mod(p),此时问题变为如何通过m=(c^(1/2))mod(p)得到x=(c^(1/2))mod(p^2),我们假定m+ps=(c^(1/2))mod(p^2),那么(m+ps)^2=cmod(p^2),即m^2+2*m*p*s+(p^2)*(s^2)=cmod(p^2),所以m^2+2*m*p*s=cmod(p^2),2*m*p*s=(c-m^2)mod(p^2)。我们已知m^2=cmod(p),即c-m^2可整除p,所以s=((c-m^2)/(2*m*p))modp(简单说明:当mp=npmod(p^2),则((m-n)*p)%(p^2)=0,要是等式成立,一定有m-n=kp,即m=nmodp),那么m+ps=(m+p*((c-m^2)/(2*m*p))),即m+ps=(m+((c-m^2)/(2*m))),即(c^(1/2))mod(p^2)的解为x=(m+(c-m^2/(2*m)))mod(p^2)(这里只是简单的完成了Hensel's lemma 的事,想知到详情可查看原定理),根据此原理可解出密文

import gmpy2
import libnum
def legendre_symbol(a, p):
    ls = pow(a, (p - 1)/2, p)
    if ls == p - 1:
        return -1
    return ls
def prime_mod_sqrt(a, p):
    a %= p
    if a == 0:
        return [0]
    if p == 2:
        return [a]
    if legendre_symbol(a, p) != 1:
        return []
    if p % 4 == 3:
        x = pow(a, (p + 1)/4, p)
        return [x, p-x]
    q, s = p - 1, 0
    while q % 2 == 0:
        s += 1
        q //= 2
    z = 1
    while legendre_symbol(z, p) != -1:
        z += 1
    c = pow(z, q, p)
    x = pow(a, (q + 1)/2, p)
    t = pow(a, q, p)
    m = s
    while t != 1:
        i, e = 0, 2
        for i in xrange(1, m):
            if pow(t, e, p) == 1:
                break
            e *= 2
        b = pow(c, 2**(m - i - 1), p)
        x = (x * b) % p
        t = (t * b * b) % p
        c = (b * b) % p
        m = i

    return [x, p-x]
def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)
def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m
# This finds a solution for c = x^2 (mod p^2)
def find_solution(c, p):
    n = p ** 2
    r = prime_mod_sqrt(c,p)[0]
    inverse_2_mod_n = modinv(2, n)
    inverse_r_mod_n = modinv(r, n)

    new_r = r - inverse_2_mod_n * (r - c * inverse_r_mod_n)

    return new_r % n

if __name__ == "__main__":
    n = 0x6b612825bd7972986b4c0ccb8ccb2fbcd25fffbadd57350d713f73b1e51ba9fc4a6ae862475efa3c9fe7dfb4c89b4f92e925ce8e8eb8af1c40c15d2d99ca61fcb018ad92656a738c8ecf95413aa63d1262325ae70530b964437a9f9b03efd90fb1effc5bfd60153abc5c5852f437d748d91935d20626e18cbffa24459d786601L
    p = 0xa5cc6d4e9f6a893c148c6993e1956968c93d9609ed70d8366e3bdf300b78d712e79c5425ffd8d480afcefc71b50d85e0914609af240c981c438acd1dcb27b301L
    c = 0xd9d6345f4f961790abb7830d367bede431f91112d11aabe1ed311c7710f43b9b0d5331f71a1fccbfca71f739ee5be42c16c6b4de2a9cbee1d827878083acc04247c6e678d075520ec727ef047ed55457ba794cf1d650cbed5b12508a65d36e6bf729b2b13feb5ce3409d6116a97abcd3c44f136a5befcb434e934da16808b0bL
    solution = find_solution(c, p)
    print hex(solution)[2:-1].decode("hex")

未完待续...............

猜你喜欢

转载自blog.csdn.net/zhang14916/article/details/81183756