攻防世界-Crypto-说我作弊需要证据(RSA解密+校验py脚本)-ISCC2017

1、说我作弊需要证据

给了一个数据包,打开追踪流发现信息,大量的base64码:
攻防世界-Crypto-说我作弊需要证据(RSA解密+校验py脚本)-ISCC2017_第1张图片

 解码几行得到:

SEQ = 13; DATA = 0x3b04b26a0adada2f67326bb0c5d6L; SIG = 0x2e5ab24f9dc21df406a87de0b3b4L;
SEQ = 0; DATA = 0x7492f4ec9001202dcb569df468b4L; SIG = 0xc9107666b1cc040a4fc2e89e3e7L;
SEQ = 5; DATA = 0x94d97e04f52c2d6f42f9aacbf0b5L; SIG = 0x1e3b6d4eaf11582e85ead4bf90a9L;
SEQ = 4; DATA = 0x2c29150f1e311ef09bc9f06735acL; SIG = 0x1665fb2da761c4de89f27ac80cbL;
SEQ = 18; DATA = 0x181901c059de3b0f2d4840ab3aebL; SIG = 0x1b8bdf9468f81ce33a0da2a8bfbeL;
SEQ = 2; DATA = 0x8a03676745df01e16745145dd212L; SIG = 0x1378c25048c19853b6817eb9363aL;
SEQ = 20; DATA = 0x674880905956979ce49af33433L; SIG = 0x198901d5373ea225cc5c0db66987L;
SEQ = 0; DATA = 0x633282273f9cf7e5a44fcbe1787bL; SIG = 0x2b15275412244442d9ee60fc91aeL;
SEQ = 28; DATA = 0x19688f112a61169c9090a4f9918dL; SIG = 0x1448ac6eee2b2e91a0a6241e590eL;
SEQ = 24; DATA = 0x59d0264d4a134fa5a91521b25e46L; SIG = 0x2bc3bf947c0e85444aa13efa1c15L;

最前面是序号,然后是Bob加密后的数据,后面是校验数据,首先根据题中信息计算出p、q、n和Bob的d,不知道这些数据是什么的话看原理:https://blog.csdn.net/zz_Caleb/article/details/89307932

因为python脚本太垃圾,又不知道RSA用什么库和函数,所以画了一段时间才搞出来。

脚本要求:gmpy2、pycrypto

1)RSA的加解密可以用python的pycrypto中的函数:from Crypto.PublicKey import RSA

2)d的运算:int(gmpy2.invert(e, A_phi))

3)还有一个把n、e、d整理到一起的函数:RSA.construct( (n, e, d) )

用把这些加解密所需数整理到一起后再进行操作,下面给出脚本:
 

from Crypto.PublicKey import RSA
import gmpy2
#Alice's
A_n = 1696206139052948924304948333474767
A_p = 38456719616722997
A_q = 44106885765559411
#Bob's
B_n = 3104649130901425335933838103517383
B_p = 49662237675630289
B_q = 62515288803124247

A_phi = (A_p - 1) * (A_q - 1)
B_phi = (B_p - 1) * (B_q - 1)

e = 65537

A_d = int(gmpy2.invert(e, A_phi))
B_d = int(gmpy2.invert(e, B_phi))
#把RSA加密系统数据整合到一起,以便下面操作
A_rsa = RSA.construct( (A_n, e, A_d) )
B_rsa = RSA.construct( (B_n, e, B_d) )

flag = ''
with open('zero_one') as f:
    for s in f.readlines():
        line = str(base64.b64decode(s), encoding = 'utf8')
        data = int(line.split('0x')[1].split('L;')[0], 16)
        sig = int(line.split('0x')[2].rstrip('L;\n'), 16)
        decry = B_rsa.decrypt(data) #RSA解密
        signcheck = A_rsa.sign(decry, '')[0]  #从明文生成的验证数据

        if signcheck == sig:      #密文生成的验证数据和从数据包中拿到的验证数据相等则为正确密文
            flag += chr(decry)

print(flag)

用生成验证数据的函数来和验证数据进行比对得出正确答案,结果:t3_01ftmg_n}h3hl3_n530rn0{g3a0_v_

顺序是乱着的,拼接的话有点难,看来还是应该考虑base64解码后,最前面的序号问题,于是修改了一下:
 

from Crypto.PublicKey import RSA
import gmpy2
import base64
#Alice's
A_n = 1696206139052948924304948333474767
A_p = 38456719616722997
A_q = 44106885765559411
#Bob's
B_n = 3104649130901425335933838103517383
B_p = 49662237675630289
B_q = 62515288803124247

A_phi = (A_p - 1) * (A_q - 1)
B_phi = (B_p - 1) * (B_q - 1)

e = 65537

A_d = int(gmpy2.invert(e, A_phi))
B_d = int(gmpy2.invert(e, B_phi))

A_rsa = RSA.construct( (A_n, e, A_d) )
B_rsa = RSA.construct( (B_n, e, B_d) )

flag = {}
with open('zero_one') as f:
    for s in f.readlines():
        line = str(base64.b64decode(s), encoding = 'utf8')
        seq = int(line.split(';')[0].split(' ')[2])
        data = int(line.split('0x')[1].split('L;')[0], 16)
        sig = int(line.split('0x')[2].rstrip('L;\n'), 16)
        decry = B_rsa.decrypt(data)
        signcheck = A_rsa.sign(decry, '')[0]

        if signcheck == sig:
            flag[seq] = chr(decry)
dic = sorted(flag.items(), key = lambda item:item[0])  #对字典按键值进行排序,返回值为列表
print(dic)
f = ''
for i in dic:
    f += i[1]
print(f)

拿到flag:flag{n0th1ng_t0_533_h3r3_m0v3_0n}

你可能感兴趣的:(python,密码知识,攻防世界)