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

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

问题描述

我正在尝试在Python中实现以下功能: openssl enc -e -aes-256-cbc -base64 -k秘密密码" -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秘密密码" -in ciphertext.txt -out Verification.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. 在CBC模式下使用AES-256和步骤2中的密钥和IV对填充进行加密.
  5. 在Base64中编码并输出步骤1中的盐.
  6. 在Base64中编码并输出第4步中的加密数据.

解密步骤相反:

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

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

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