如何在Python中解密OpenSSL AES加密的文件? [英] How to decrypt OpenSSL AES-encrypted files in Python?

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

问题描述

OpenSSL为AES加密提供了一个流行的(但不安全-见下文!)命令行界面:

OpenSSL provides a popular (but insecure – see below!) command line interface for AES encryption:

openssl aes-256-cbc -salt -in filename -out filename.enc

Python以PyCrypto软件包的形式支持AES,但仅提供工具.如何使用Python/PyCrypto解密使用OpenSSL加密的文件?

Python has support for AES in the shape of the PyCrypto package, but it only provides the tools. How to use Python/PyCrypto to decrypt files that have been encrypted using OpenSSL?

这个问题过去也涉及使用相同方案在Python中进行加密.此后,我删除了该部分,以阻止任何人使用它.请勿以这种方式加密更多数据,因为按照当今的标准,这些数据并不安全.仅应使用解密,除向后兼容性外,即没有其他选择时,不要使用其他任何原因.要加密吗?如果可以的话,请使用NaCl/libsodium.

This question used to also concern encryption in Python using the same scheme. I have since removed that part to discourage anyone from using it. Do NOT encrypt any more data in this way, because it is NOT secure by today's standards. You should ONLY use decryption, for no other reasons than BACKWARD COMPATIBILITY, i.e. when you have no other choice. Want to encrypt? Use NaCl/libsodium if you possibly can.

推荐答案

鉴于Python的普及,起初我很失望,因为找不到这个问题的完整答案.我花了很多时间在黑板上阅读不同的答案以及其他资源,以使其正确.我认为我可以分享结果以供将来参考和审查.我绝不是密码专家!但是,以下代码似乎可以无缝运行:

Given the popularity of Python, at first I was disappointed that there was no complete answer to this question to be found. It took me a fair amount of reading different answers on this board, as well as other resources, to get it right. I thought I might share the result for future reference and perhaps review; I'm by no means a cryptography expert! However, the code below appears to work seamlessly:

from hashlib import md5
from Crypto.Cipher import AES
from Crypto import Random

def derive_key_and_iv(password, salt, key_length, iv_length):
    d = d_i = ''
    while len(d) < key_length + iv_length:
        d_i = md5(d_i + password + salt).digest()
        d += d_i
    return d[:key_length], d[key_length:key_length+iv_length]

def decrypt(in_file, out_file, password, key_length=32):
    bs = AES.block_size
    salt = in_file.read(bs)[len('Salted__'):]
    key, iv = derive_key_and_iv(password, salt, key_length, bs)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    next_chunk = ''
    finished = False
    while not finished:
        chunk, next_chunk = next_chunk, cipher.decrypt(in_file.read(1024 * bs))
        if len(next_chunk) == 0:
            padding_length = ord(chunk[-1])
            chunk = chunk[:-padding_length]
            finished = True
        out_file.write(chunk)

用法:

with open(in_filename, 'rb') as in_file, open(out_filename, 'wb') as out_file:
    decrypt(in_file, out_file, password)

如果您有机会对此进行改进或扩展,使其更加灵活(例如,使其在不加盐的情况下就可以正常工作,或者提供Python 3兼容性),请随时这样做.

If you see a chance to improve on this or extend it to be more flexible (e.g. make it work without salt, or provide Python 3 compatibility), please feel free to do so.

该答案过去也涉及使用相同方案在Python中进行加密.此后,我删除了该部分,以阻止任何人使用它.请勿以这种方式加密更多数据,因为按照当今的标准,这些数据并不安全.仅应使用解密,除向后兼容性外,即没有其他选择时,不要使用其他任何原因.要加密吗?如果可以的话,请使用NaCl/libsodium.

This answer used to also concern encryption in Python using the same scheme. I have since removed that part to discourage anyone from using it. Do NOT encrypt any more data in this way, because it is NOT secure by today's standards. You should ONLY use decryption, for no other reasons than BACKWARD COMPATIBILITY, i.e. when you have no other choice. Want to encrypt? Use NaCl/libsodium if you possibly can.

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

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