CTF中用对称密钥与IV解密Base64字符串遇IV长度错误求助
AES解密IV长度错误问题解决
在CTF竞赛中,尝试用对称密钥和IV解密Base64字符串时,触发错误:
ValueError: Incorrect IV length (it must be 16 bytes long)
题目规则
Now, you can put together the first eight bytes of all the codes you have found so far.
These bytes will give you a symmetric key to decrypt a secret provided by this HTTP response.
You may also need an IV, and perhaps it will be on the last eight bytes of each code. Good luck!
可用Flags
02c1ef500ae2ae040ceb904d2d1014 8796f067cc814c8c632e6be8d2dbc9 89510d842231dad07b2a162c43d040 5b7c1a981199072d95384083d12b9c
待解密Base64字符串
6dU2tgevONWUv6ZWu+84g7E4r4dKOfBxRiY3jnMf2m1aE4r1AZcOztzEKtwve2z211vOnoiXWJTGWTG6wQxibFDw+tVI8hAGwQMqYqeG963g+wz2ppMP+byEcvAgfwvmLrsgm/+nLFxCeKLWYy/e625RmmNEU06s1Dz6izYXX1PNiYn+JAcZQnS1N5KiuvjX1u2qWAIkAPY2H5/BO25vEg==
原代码
from Crypto.Cipher import AES from Crypto.Util.Padding import unpad import base64 flags = [ "02c1ef500ae2ae040ceb904d2d1014", "8796f067cc814c8c632e6be8d2dbc9", "89510d842231dad07b2a162c43d040", "5b7c1a981199072d95384083d12b9c" ] key_hex = flags[0][:16] + flags[1][:16] + flags[2][:16] + flags[3][:16] key = bytes.fromhex(key_hex) iv_hex = flags[0][-16:] + flags[1][-16:] + flags[2][-16:] + flags[3][-16:] iv = bytes.fromhex(iv_hex) cipher_b64 = """6dU2tgevONWUv6ZWu+84g7E4r4dKOfBxRiY3jnMf2m1aE4r1AZcOztzEKtwve2z211vOnoiXWJTGWTG6wQxibFDw+tVI8hAGwQMqYqeG963g+wz2ppMP+byEcvAgfwvmLrsgm/+nLFxCeKLWYy/e625RmmNEU06s1Dz6izYXX1PNiYn+JAcZQnS1N5KiuvjX1u2qWAIkAPY2H5/BO25vEg==""" encrypted_data = base64.b64decode(cipher_b64) cipher = AES.new(key, AES.MODE_CBC, iv) decrypted = cipher.decrypt(encrypted_data) plaintext = unpad(decrypted, AES.block_size).decode('utf-8') print(plaintext)
问题分析
错误根源是生成的IV长度不符合要求:
- AES-CBC模式要求IV必须是16字节,但原代码中每个flag取最后16个十六进制字符(对应8字节),四个拼接后得到64个十六进制字符,转成字节是32,远超16字节限制。
- 观察提供的flag,每个flag的字符数不足32(比如第一个flag只有29个),说明要么flag复制不完整,要么误解了规则中“last eight bytes”的含义——实际应为每个flag的最后8个十六进制字符(对应4字节),四个拼接后得到32个十六进制字符,转成字节正好是16。
修正后的代码
from Crypto.Cipher import AES from Crypto.Util.Padding import unpad import base64 flags = [ "02c1ef500ae2ae040ceb904d2d1014", "8796f067cc814c8c632e6be8d2dbc9", "89510d842231dad07b2a162c43d040", "5b7c1a981199072d95384083d12b9c" ] # 密钥:每个flag取前16个十六进制字符(8字节),拼接成32字节(AES-256) key_hex = flags[0][:16] + flags[1][:16] + flags[2][:16] + flags[3][:16] key = bytes.fromhex(key_hex) # IV:每个flag取最后8个十六进制字符(4字节),拼接成16字节 iv_hex = flags[0][-8:] + flags[1][-8:] + flags[2][-8:] + flags[3][-8:] iv = bytes.fromhex(iv_hex) cipher_b64 = """6dU2tgevONWUv6ZWu+84g7E4r4dKOfBxRiY3jnMf2m1aE4r1AZcOztzEKtwve2z211vOnoiXWJTGWTG6wQxibFDw+tVI8hAGwQMqYqeG963g+wz2ppMP+byEcvAgfwvmLrsgm/+nLFxCeKLWYy/e625RmmNEU06s1Dz6izYXX1PNiYn+JAcZQnS1N5KiuvjX1u2qWAIkAPY2H5/BO25vEg==""" encrypted_data = base64.b64decode(cipher_b64) cipher = AES.new(key, AES.MODE_CBC, iv) decrypted = cipher.decrypt(encrypted_data) plaintext = unpad(decrypted, AES.block_size).decode('utf-8') print(plaintext)
如果你的flag是完整的32个十六进制字符(16字节),则可以保留每个flag取最后16个十六进制字符的逻辑,但需要将IV截断为16字节:
iv_hex = flags[0][-16:] + flags[1][-16:] + flags[2][-16:] + flags[3][-16:] iv = bytes.fromhex(iv_hex)[:16] # 截断为16字节
内容的提问来源于stack exchange,提问作者noobProgrammer
相关产品推荐
相关产品推荐

