(python3环境)
描述:Alice和Bob使用某些加密方式隐藏通信内容躲过老师视线
Alice的RSA密钥为(n, e) = (0x53a121a11e36d7a84dde3f5d73cf, 0x10001) IP地址(192.168.0.13)
Bob的RSA密钥为(n, e) =(0x99122e61dc7bede74711185598c7, 0x10001) IP地址(192.168.0.37)
打开.pcapng分析:
主要集中在TCP协议
常见都会分析Length属性:
后面开始出现类似Base64编码:
注意到后面还有一大堆,右键直接追踪流:
上述所有内容存在新建data.txt中:
from base64 import b64decode
with open('data.txt', 'r') as f: # str读取模式
data = f.read() # 返回字节序列
cips = data.split('\n')
decoded_data = []
# 对每一行数据进行解码并提取需要的部分
for cip in cips[:-1]:
data_bytes = b64decode(cip) # 解码得到的是字节流
data = data_bytes.decode() # 解码为字符串 默认utf-8
# 提取 seq, cipher 和 sig 的数值
seq = int(data[(data.find('= ') + 2):data.find(';')])
cipher = int(data[(data.find('x') + 1):data.find('L')], 16)
sig = int(data[(data.rfind('x') + 1):data.rfind('L')], 16)
# 将解码后的数据和 seq 一起存储
decoded_data.append((seq, cipher, sig))
# 按照 seq 升序排序
decoded_data.sort(key=lambda x: x[0])
# 输出按升序排列的解码数据
for seq, cipher, sig in decoded_data:
print(seq, cipher, sig)
进制转换且排序,只提取数字,得到形如下方数据:
........
关于流程和变量的说明:
Alice --> IP地址(192.168.0.13)
Bob --> IP地址(192.168.0.37)
base64编码全是Alice发给Bob的部分
Alice的RSA密钥(e,d1,N1)
Bob的RSA密钥(e,d2,N2)
由于是Bob接收到密文,自然是Bob解密:m = c ^ d2 mod N2
Alice用公钥为明文签名(验证密文解密是否准确),所以m = c ^ e mod N1
(大部分情况下,签名和密文都会一起送到) ---- 这边只涉及到加密信息的签名,而不是发送方身份验证的签名
SEQ:序号
DATA:密文(Cipher)
SIG:签名(验证密文正确性)
解密脚本:
传入的文件是之前升序且进制转换的数据.txt
import gmpy2
import rsa
from Crypto.Util.number import long_to_bytes
N1 = 1696206139052948924304948333474767 # 0x53a121a11e36d7a84dde3f5d73cf
N2 = 3104649130901425335933838103517383 # 0x99122e61dc7bede74711185598c7
e = 65537 # 0x10001
p2 = 49662237675630289 # 49662237675630289L
q2 = 62515288803124247 # 62515288803124247L
phi2 = (p2 - 1) * (q2 - 1)
d2 = gmpy2.invert(e, phi2)
privatekey = rsa.PrivateKey(N2, e, d2, p2, q2)
data = []
with open('sort_decode_data.txt', 'r') as f:
for line in f: # line.strip(去除两端的空白字符)
parts = line.strip().split() # " 123 456 789 ".split() # 输出 ['123', '456', '789']
seq = int(parts[0])
cipher = int(parts[1])
sign = int(parts[2])
data.append((cipher, sign))
res = []
for cipher, sig in data:
plain_text = pow(cipher, d2, N2)
verify_sign = pow(sig, e, N1)
if plain_text == verify_sign:
res.append(long_to_bytes(plain_text))
print(f"Valid: {long_to_bytes(plain_text)}")
else:
print(f"Invalid: Cipher: {cipher}, Signature: {sig}")
# print(res)
print(''.join(i.decode() for i in res))
flag{n0th1ng_t0_533_h3r3_m0v3_0n}
(高手请看:)
!!部分问题,求解惑:
差点被题目单杀,调用模块和python2一直不兼容 [心碎],应该是我有问题
起初参考(python2):攻防世界 Crypto高手进阶区 5分题 说我作弊需要证据_攻防世界 x老师怀疑一些调皮的学生-CSDN博客
from Crypto.Util.number import long_to_bytes, bytes_to_long
本来是想用上述库,处理对其密文作为参数的格式要求
(因为参考代码是在python2环境运行,似乎rsa.decrypt(cipher,rsa_key)里的cipher允许大整数long形式,但是我怎么都不行,可能是我版本的原因,没有细究了,后面要是有大神处理好python2的代码,麻烦call我一下)
msg = rsa.decrypt(long_to_bytes(cipher), rsa_key2)
参数类型bytes,long都换了;换建议的库也换了,问题仍没解决