在 Python 中实现 OpenSSL AES 加密 [英] Implement OpenSSL AES Encryption in Python

查看:97
本文介绍了在 Python 中实现 OpenSSL AES 加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 Python 中实现以下内容:openssl enc -e -aes-256-cbc -base64 -k "Secret Passphrase" -in plaintext.txt -out ciphertext.txt

I'm trying to implement the following in Python: openssl enc -e -aes-256-cbc -base64 -k "Secret Passphrase" -in plaintext.txt -out ciphertext.txt

openssl enc -d -aes-256-cbc -base64 -k "Secret Passphrase" -in ciphertext.txt -out verify.txt

openssl enc -d -aes-256-cbc -base64 -k "Secret Passphrase" -in ciphertext.txt -out verification.txt

我尝试了几种不同的模块,PyCrypto、M2Crypto 等,但似乎无法获得将密码更改为正确大小的密钥并正确编码所有内容的正确组合.我找到了 https://github.com/nvie/SimpleAES 但这基本上是在命令上运行 OpenSSL线,我宁愿避免.

I've tried several different modules, PyCrypto, M2Crypto, etc but can't seem to get the correct combination of changing the password to the right size key and encoding everything correctly. I've found https://github.com/nvie/SimpleAES but that basically runs OpenSSL on the command line, which I'd rather avoid.

推荐答案

Base 64 编码和解码可以通过标准的 base64 模块轻松处理.

Base 64 encoding and decoding can be easily handled via the standard base64 module.

PyCrypto 和 M2Crypto 均支持 CBC 模式下的 AES-256 解密和加密.

AES-256 decryption and encryption in CBC mode are supported by both PyCrypto and M2Crypto.

唯一非标准(也是最困难)的部分是从密码推导 IV 和密钥.OpenSSL 通过它自己的 EVP_BytesToKey 函数来实现,该函数在 中进行了描述这个手册页.

The only non-standard (and most difficult) part is the derivation of the IV and the key from the password. OpenSSL does it via its own EVP_BytesToKey function, which is described in this man page.

Python 等价物是:

The Python equivalent is:

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)<(iv_len+key_len):
        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.

where key_len is 32 and iv_len is 16 for AES-256. The function returns the key and the IV which you can use to decrypt the payload.

OpenSSL 在加密负载的前 8 个字节中放置并期望加盐.

OpenSSL puts and expects the salt in the first 8 bytes of the encrypted payload.

最后,CBC 模式下的 AES 只能处理与 16 字节边界对齐的数据.使用的默认填充是 PKCS#7.

Finally, AES in CBC mode can only work with data aligned to the 16 byte boundary. The default padding used is PKCS#7.

因此加密步骤是:

  1. 生成 8 字节的随机数据作为盐.
  2. 使用第 1 步中的盐从密码中导出 AES 密钥和 IV.
  3. 使用 PKCS#7 填充输入数据.
  4. 使用 AES-256 在 CBC 模式下使用密钥和步骤 2 中的 IV 加密填充.
  5. 以 Base64 编码并输出步骤 1 中的盐.
  6. 以 Base64 编码并输出步骤 4 中的加密数据.

解密的步骤是相反的:

  1. 将 Base64 中的输入数据解码为二进制字符串.
  2. 将解码数据的前 8 个字节视为盐.
  3. 使用第 1 步中的盐从密码中导出 AES 密钥和 IV.
  4. 使用 AES 密钥和步骤 3 中的 IV 解密剩余的解码数据.
  5. 验证并从结果中删除 PKCS#7 填充.

这篇关于在 Python 中实现 OpenSSL AES 加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆