from Crypto.Cipher import AES from Crypto.PublicKey import RSA from secrets import my_rsa_key_generator, key, flag def pad(data): pad_size = AES.block_size - len(data) % AES.block_size return data + pad_size * bytes([pad_size]) n, e, d, p, q = my_rsa_key_generator(nbits = 4096) rsa_key = RSA.construct((n, e, d, p, q)) pub_der = rsa_key.publickey().exportKey('DER') priv_der = rsa_key.exportKey('DER') # AES-ECB is safe, right? :) aes_ecb = AES.new(key, AES.MODE_ECB) priv_der_enc = aes_ecb.encrypt(pad(priv_der)) flag_enc = rsa_key.encrypt(flag, None)[0] open('pub.der', 'wb').write(pub_der) open('priv.der.enc', 'wb').write(priv_der_enc) open('flag.enc', 'wb').write(flag_enc)
AES-ECB
AES-ECB、というよりECBモードは同じ平文に対して同じ暗号文を生成する。
これを利用して、FLAG | 任意の平文
を暗号化できる場合 に(当然 任意の平文 | FLAG
とか ごみ | 任意の平文 | FLAG
の場合にも)FLAGを得られたりする(単にChosen Plaintext Attackと呼ばれていると思う)
他には、平文にパターンが存在した場合にそれが露出する、という場合もある。ECBモードをわざわざ使っている場合、このどちらかであることが多いので疑っていきたい。