ctf crypto 入门总结(下)-RSA

RSA加密

RSA openssl加解密

查看公钥openssl rsa -pubin -in pub.key -text -modulus
解密代码openssl rsautl -decrypt -inkey pub.key -in flag.enc -out flag(私钥题目一般不会给的吧...)

代码解密

#python2
def RSA_decrypt(p,q,e,c):
    from Crypto.Util.number import long_to_bytes
    import primefac
    def modinv(a,n):
        return primefac.modinv(a,n)%n
    n=p*q
    d=modinv(e,(p-1)*(q-1))
    m=pow(c,d,n)
    return long_to_bytes(m)
p=
q=
e=
c=
print RSA_decrypt(p,q,e,c)

直接模数分解

分解网站:
http://www.factordb.com/

一些与素数相关的函数
#python2
from Crypto.Util.number import isPrime,getPrime
a=getPrime(1024) #生成一个1024二进制位的素数
print a
print isPrime(a) #判断a是不是素数
#python3
import sympy
sympy.prime(n) #生成第n个素数
sympy.isprime(a) #判断a是不是素数
sympy.primepi(n) #返回小于n的素数的总数
sympy.nextprime(n) #返回下一个素数
sympy.prevprime(n) #返回上一个素数
解方程

(想当年,我网空导论就在解方程上翻的车)
方程组:

#python3
import sympy
c1=2732509502629189160482346120094198557857912754
c2=5514544075236012543362261483183657422998274674127032311399076783844902086865451355210243586349132992563718009577051164928513093068525554
x=sympy.Symbol('x')
y=sympy.Symbol('y')
f1=x+y-c1
f2=x**3+y**3-c2
print(sympy.solve([f1,f2],[x,y])) 

(三次方程也可以解出来,是我没想到的)

小指数明文爆破

例:buuctf平台 dangerous RSA
题目:
n: 0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793L
e: 0x3
c:0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365
so,how to get the message?

打开题目,发现e很小为3,则可以确定使用小指数明文爆破

#python2
from Crypto.Util.number import long_to_bytes
import primefac
def modinv(a,n):
    return primefac.modinv(a,n)%n
n=0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793
e=0x3
c=0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365
import gmpy2
i=0
while 1:
    if(gmpy2.iroot(c+i*n,3)[1]==1):
        print long_to_bytes(gmpy2.iroot(c+i*n,3)[0])
        break
    i+=1

LLL-attack

例:buuctf平台 babycrypto
题目: n:0xb119849bc4523e49c6c038a509a74cda628d4ca0e4d0f28e677d57f3c3c7d0d876ef07d7581fe05a060546fedd7d061d3bc70d679b6c5dd9bc66c5bdad8f2ef898b1e785496c4989daf716a1c89d5c174da494eee7061bcb6d52cafa337fc2a7bba42c918bbd3104dff62ecc9d3704a455a6ce282de0d8129e26c840734ffd302bec5f0a66e0e6d00b5c50fa57c546cff9d7e6a978db77997082b4cb927df9847dfffef55138cb946c62c9f09b968033745b5b6868338c64819a8e92a827265f9abd409359a9471d8c3a2631b80e5b462ba42336717700998ff38536c2436e24ac19228cd2d7a909ead1a8494ff6c3a7151e888e115b68cc6a7a8c6cf8a6c005L
e:65537
enc:1422566584480199878714663051468143513667934216213366733442059106529451931078271460363335887054199577950679102659270179475911101747625120544429262334214483688332111552004535828182425152965223599160129610990036911146029170033592055768983427904835395850414634659565092191460875900237711597421272312032796440948509724492027247376113218678183443222364531669985128032971256792532015051829041230203814090194611041172775368357197854451201260927117792277559690205342515437625417792867692280849139537687763919269337822899746924269847694138899165820004160319118749298031065800530869562704671435709578921901495688124042302500361
p>>128<<128:0xe4e4b390c1d201dae2c00a4669c0865cc5767bc444f5d310f3cfc75872d96feb89e556972c99ae20753e3314240a52df5dccd076a47c6b5d11b531b92d901b2b512aeb0b263bbfd624fe3d52e5e238beeb581ebe012b2f176a4ffd1e0d2aa8c4d3a2656573b727d4d3136513a931428b00000000000000000000000000000000L

知道了p的一部分,解密代码为:

#sagemath
n = 0xb119849bc4523e49c6c038a509a74cda628d4ca0e4d0f28e677d57f3c3c7d0d876ef07d7581fe05a060546fedd7d061d3bc70d679b6c5dd9bc66c5bdad8f2ef898b1e785496c4989daf716a1c89d5c174da494eee7061bcb6d52cafa337fc2a7bba42c918bbd3104dff62ecc9d3704a455a6ce282de0d8129e26c840734ffd302bec5f0a66e0e6d00b5c50fa57c546cff9d7e6a978db77997082b4cb927df9847dfffef55138cb946c62c9f09b968033745b5b6868338c64819a8e92a827265f9abd409359a9471d8c3a2631b80e5b462ba42336717700998ff38536c2436e24ac19228cd2d7a909ead1a8494ff6c3a7151e888e115b68cc6a7a8c6cf8a6c005L
p_fake = 0xe4e4b390c1d201dae2c00a4669c0865cc5767bc444f5d310f3cfc75872d96feb89e556972c99ae20753e3314240a52df5dccd076a47c6b5d11b531b92d901b2b512aeb0b263bbfd624fe3d52e5e238beeb581ebe012b2f176a4ffd1e0d2aa8c4d3a2656573b727d4d3136513a931428b00000000000000000000000000000000L

pbits = 1024
kbits = 128
pbar = p_fake & (2^pbits-2^kbits)
print ("upper %d bits (of %d bits) is given" % (pbits-kbits, pbits))

PR.<x> = PolynomialRing(Zmod(n))
f = x + pbar
x0 = f.small_roots(X=2^kbits, beta=0.4)[0]  # find root < 2^kbits with factor >= n^0.3
p = int(x0 + pbar)
print('p=',p)

通过sage解出p,再进行正常解密

#python2
def RSA_decrypt(p,q,e,c):
    from Crypto.Util.number import long_to_bytes
    import primefac
    def modinv(a,n):
        return primefac.modinv(a,n)%n
    n=p*q
    d=modinv(e,(p-1)*(q-1))
    m=pow(c,d,n)
    return long_to_bytes(m)
p=160734387026849747944319274262095716650717626398118440194223452208652532694713113062084219512359968722796763029072117463281356654614167941930993838521563406258263299846297499190884495560744873319814150988520868951045961906000066805136724505347218275230562125457122462589771119429631727404626489634314291445667
n=0xb119849bc4523e49c6c038a509a74cda628d4ca0e4d0f28e677d57f3c3c7d0d876ef07d7581fe05a060546fedd7d061d3bc70d679b6c5dd9bc66c5bdad8f2ef898b1e785496c4989daf716a1c89d5c174da494eee7061bcb6d52cafa337fc2a7bba42c918bbd3104dff62ecc9d3704a455a6ce282de0d8129e26c840734ffd302bec5f0a66e0e6d00b5c50fa57c546cff9d7e6a978db77997082b4cb927df9847dfffef55138cb946c62c9f09b968033745b5b6868338c64819a8e92a827265f9abd409359a9471d8c3a2631b80e5b462ba42336717700998ff38536c2436e24ac19228cd2d7a909ead1a8494ff6c3a7151e888e115b68cc6a7a8c6cf8a6c005L
q=n/p
e=65537
c=1422566584480199878714663051468143513667934216213366733442059106529451931078271460363335887054199577950679102659270179475911101747625120544429262334214483688332111552004535828182425152965223599160129610990036911146029170033592055768983427904835395850414634659565092191460875900237711597421272312032796440948509724492027247376113218678183443222364531669985128032971256792532015051829041230203814090194611041172775368357197854451201260927117792277559690205342515437625417792867692280849139537687763919269337822899746924269847694138899165820004160319118749298031065800530869562704671435709578921901495688124042302500361
print RSA_decrypt(p,q,e,c)
共模攻击

例:buuctf平台 samemod
打开题目:
{6266565720726907265997241358331585417095726146341989755538017122981360742813498401533594757088796536341941659691259323065631249,773}
{6266565720726907265997241358331585417095726146341989755538017122981360742813498401533594757088796536341941659691259323065631249,839}

message1=3453520592723443935451151545245025864232388871721682326408915024349804062041976702364728660682912396903968193981131553111537349
message2=5672818026816293344070119332536629619457163570036305296869053532293105379690793386019065754465292867769521736414170803238309535

n1和n2相等,可以确定为共模攻击
解密代码:

from Crypto.Util.number import long_to_bytes
import primefac
def same_n_sttack(n,e1,e2,c1,c2):
    def egcd(a,b):
        x,lastX=0,1
        y,lastY=1,0
        while(b!=0):
            q = a//b
            a,b=b,a%b
            x,lastX=lastX-q*x,x
            y,lastY=lastY-q*y,y
        return(lastX,lastY)
    s=egcd(e1,e2)
    s1=s[0]
    s2=s[1]
    if s1<0 :
        s1= -s1
        c1= primefac.modinv(c1,n)
        if c1<0:
            c1+=n
    elif s2<0:
        s2 = -s2
        c2 = primefac.modinv(c2,n)
        if c2<0:
            c2+=n
    m=(pow(c1,s1,n)*pow(c2,s2,n))%n
    return m
n1=6266565720726907265997241358331585417095726146341989755538017122981360742813498401533594757088796536341941659691259323065631249
e1=773
c1=3453520592723443935451151545245025864232388871721682326408915024349804062041976702364728660682912396903968193981131553111537349
e2=839
c2=5672818026816293344070119332536629619457163570036305296869053532293105379690793386019065754465292867769521736414170803238309535
m=(same_n_sttack(n1,e1,e2,c1,c2))
result=str(m)
flag=""
i=0
while i < len(result):
    if result[i]=='1':
        c=chr(int(result[i:i+3]))
        i+=3
    else:
        c=chr(int(result[i:i+2]))
        i+=2
    flag+=c
print flag
原文地址:https://www.cnblogs.com/yhr001/p/13516274.html