AES 解密实践之代码实现
上篇提到对于AES解密,命令行无法处理key截断的问题。
看一下实测代码,目前只测试到OpenSSL可以正确解密,但是库函数无法正确解密。
1. CFB模式代码展示
from Crypto.Cipher import AES
import base64
import binascii
import subprocessiv_hex = "5475faa137f4df508d643a1e9239a6f0"
iv = bytes.fromhex(iv_hex)key_hex = "476d6a73744b6947696c5056525a756d6d73524f4f332f704d724a4e7650686c"
key = binascii.unhexlify(key_hex)ciphertext_b64 = """CyU51Wb6TvcUrLmSpoc7Nkh6m1AvctGq/GwdMME8pAk50fL9FVoy9p5DlVII3BHI
JeScMzpb4svLw0cE81U5YKu7lEGD9twQKxEwK2AEuw+XtL3wn36ky6PMTZ76JGTw
fdHk4N9RtEUHEyC94GvjU3sye5UXyNGVUTvcvVZYexmDHcM12M0V4rhEpyUrZ0jL
2dfdXGeYxiuqI1fH8V/BD4mXKtWcrfzDl+45O5XjSWrUj0YC6GA+QOzPBWMgnQ=="""# 解码 Base64 编码的密文
ciphertext = base64.b64decode(ciphertext_b64)# 创建 AES-CFB 解密对象
cipher_decrypt = AES.new(key, AES.MODE_CFB, iv)# 解密
decrypted = cipher_decrypt.decrypt(ciphertext)# 打印解密结果
try:print("解密结果:", decrypted.decode('utf-8'))
except UnicodeDecodeError as e:print("Error decoding UTF-8:", e)# 将密文保存到文件
with open("ciphertextcfb.b64", "w") as f:f.write(ciphertext_b64)# 使用 OpenSSL 命令行工具进行解密
subprocess.run(["openssl", "enc", "-aes-256-cfb", "-d", "-in", "ciphertextcfb.b64", "-out", "decryptedtestcfb.bin", "-base64", "-K", key_hex, "-iv", iv_hex
])
2. 差异分析:CFB 模式与 CBC 模式的密钥处理差异
2.1. 工作原理
CFB 模式
- 特性: CFB(Cipher Feedback)模式是流模式。
- 加密过程: 将加密数据块流的输出用作下一个数据块的输入。
- 密钥要求: 密钥和 IV 的完整性对每个加密块至关重要。
- 影响: 如果密钥被截断,会导致加密和解密过程中产生不一致的结果,最终可能导致解密失败或错误的输出。
CBC 模式
- 特性: CBC(Cipher Block Chaining)模式是块模式。
- 加密过程: 使用前一个加密块的输出与当前明文块进行异或运算。
- 密钥要求: 尽管完整性仍然重要,但截断密钥可能不会立即影响每个块的解密。
- 影响: 如果前面的块能够正确解密,后面的块可能仍然产生可读的输出。
2.2. 为什么 CFB 不能处理截断
- 反馈机制: CFB 模式依赖于前一个加密操作的输出,截断密钥会影响每一步的加密和解密过程。
- 流加密特性: 每个字节都与密钥和 IV 紧密相关,任何密钥的变化都会显著影响输出。
2.3. 为什么 CBC 可以在某种程度上处理截断
- 块加密特性: CBC 模式处理固定大小的数据块,截断密钥可能不会立即影响每个块的解密。
- 数据依赖性: 如果前面的块能够正确解密,后面的块可能会受到前面块的影响。
3. 为什么OpenSSL中可以处理截断的CFB模式的key
- OpenSSL 的密钥处理灵活性
密钥长度自动调整: OpenSSL 可能对密钥长度的处理更为宽松,能够在某些情况下自动调整或填充密钥。这意味着即使你提供了一个截断的密钥,OpenSSL 可能会用特定的方法来处理这个密钥。 - IV 和加密参数的一致性
一致的 IV: 如果在加密和解密过程中使用了相同的初始化向量(IV),而且 IV 是正确的,那么 OpenSSL 可能能恢复出原始数据,即使密钥被截断。 - 默认行为和容错性
OpenSSL 的默认行为: OpenSSL 在处理加密时可能有一定的容错性或默认行为,允许某些不严格的输入条件。
当然这些原因是可能性比较大的,至于真正是什么原因,目前没有测试出来。
4. 解决方案
- 尽可能使用OpenSSL命令行处理。
5. 下一步方案
为了验证库函数是否能处理CFB模式下,截断Key的问题,下次在代码中选用长度超过32字节的key,通过库函数生成密文。然后利用截断的key来尝试解密,验证是否是因为key的截断导致无法正确解密CFB模式的密文。
总结
- CFB 模式对密钥的完整性要求更高,截断会导致解密失败。
- CBC 模式可能在某些情况下仍能产生可读输出,但这并不是安全的做法,避免截断密钥是最佳实践。