Base 64编码和解码可以通过标准的base64模块轻松处理。
PyCrypto和M2Crypto都支持CBC模式下的AES-256解密和加密。
唯一的非标准(也是最困难的)部分是从密码派生IV和密钥。OpenSSL是通过它自己的EVP_BytesToKey函数来实现的,这个函数被描述为in this man page。
与Python等价的是:def EVP_BytesToKey(password, salt, key_len, iv_len):
"""
Derive the key and the IV from the given password and salt.
"""
from hashlib import md5
dtot = md5(password + salt).digest()
d = [ dtot ]
while len(dtot)
d.append( md5(d[-1] + password + salt).digest() )
dtot += d[-1]
return dtot[:key_len], dtot[key_len:key_len+iv_len]
其中,AES-256的key_len是32,而iv_len是16。该函数返回可用于解密有效负载的密钥和IV。
OpenSSL在加密有效负载的前8个字节中放入并期望salt。
最后,CBC模式下的AES只能处理与16字节边界对齐的数据。使用的默认填充是PKCS#7。
因此,加密的步骤是:生成8字节的随机数据作为salt。
使用步骤1中的salt从密码派生AES密钥和IV。
用PKCS#7填充输入数据。
在CBC模式下,使用AES-256使用步骤2中的密钥和IV对padded进行加密。
在Base64中编码并从步骤1输出盐。
在Base64中编码并输出步骤4中的加密数据。
解密的步骤与此相反:将输入数据从Base64解码为二进制字符串。
将解码数据的前8个字节视为salt。
使用步骤1中的salt从密码派生AES密钥和IV。
使用AES密钥和步骤3中的IV解密剩余的解码数据。
验证并从结果中移除PKCS#7填充。