概述
RsaCtfTool是来自于HTB(hackthebox.com)的一个容易级密码学挑战,完成该挑战所需要掌握的知识点包括RSA加密, AES加密以及公钥文件。
题目分析
相关的任务文件提供了flag.txt.aes
,key
和pubkey.pem
三个文件。flag.txt.aes
是一个二进制文件, key
文件中是一串16进制数,而pubkey.pem
则是一个公钥文件。
解题思路
任务说明中没有提供明确的线索,通过flag.txt.aes
的文件名我们可以猜测.aes
后缀代表该文件是对明文通过AES加密生成。 而AES解密需要一个密钥,应该与key
有关。
解题过程
我们首先使用RsaCtfTool
这个工具来分析pubkey.pem
。
$ RsaCtfTool.py --publickey pubkey.pem
private argument is not set, the private key will not be displayed, even if recovered.
[*] Testing key pubkey.pem.
attack initialized...
...
[*] Performing nonRSA attack on pubkey.pem.
n = 10410080216253956216713537817182443360779235033823514652866757961082890116671874771565125457104853470727423173827404139905383330210096904014560996952285911^3
d = 129275315911223317359903751663807516352090026808195570114389567583720564611378335627134085402837298827247544997735787221623420069090831026403341043627337118073514316414863510575197151252044137503590414785481554107787977492191190932914467213110568469344259204522660239854742719334572977699979751357274672629248833545002097445009562614595500619383316585368090022534207869125569280525912198666917266810668438225654808711335777444218772562879952971915504193507508773
[!] Since this is not a valid RSA key, attempts to display the private key will fail
[*] Attack success with nonRSA method !
运行结果告诉我们pubkey.pem
不是一个RSA公钥文件, 同时给出了n
和d
的数值。 而n
和d
可以用于RSA解密。
由此,我们使用pubkey.pem
中的信息来对key
进行RSA解密。
from Crypto.Util.number import bytes_to_long, long_to_bytes
N = pow(10410080216253956216713537817182443360779235033823514652866757961082890116671874771565125457104853470727423173827404139905383330210096904014560996952285911, 3)
d = 129275315911223317359903751663807516352090026808195570114389567583720564611378335627134085402837298827247544997735787221623420069090831026403341043627337118073514316414863510575197151252044137503590414785481554107787977492191190932914467213110568469344259204522660239854742719334572977699979751357274672629248833545002097445009562614595500619383316585368090022534207869125569280525912198666917266810668438225654808711335777444218772562879952971915504193507508773
## key文件中的密文
c = 0x13822f9028b100e2b345a1ad989d9cdedbacc3c706c9454ec7d63abb15b58bef8ba545bb0a3b883f91bf12ca12437eb42e26eff38d0bf4f31cf1ca21c080f11877a7bb5fa8ea97170c932226eab4812c821d082030100030d84ebc63fd8767cde994e0bd1a1f905c27fb0d7adb55e3a1f101d8b5b997ba6b1c09a5e1cc65a9206906ef5e01f13d7beeebdf389610fb54676f76ec0afc51a304403d44bb3c739fd8276f0895c3587a710d15e43fc67284070519e6e0810caf86b134f02ec54018
## 计算明文
m = pow(c, d, N)
long_to_bytes(m)
## b'secretkey\x96\x1dW\xbe\xc09<'
通过以上计算, 我们可以得到key
的明文, 可用于对flag.txt.aes
进行AES解密。
from Crypto.Cipher import AES
## 读取flag.txt.aes文件内容
with open("flag.txt.aes", mode='rb') as file:
data = file.read()
## 初始化AES, 使用key的明文作为密钥, 使用ECB模式
aes = AES.new(m, AES.MODE_ECB)
## flag.txt.aes文件大小为33个字节,忽略结尾的一个字节
plantext = aes.decrypt(data[:32])
print("FLAG:", plantext)