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

查看:42
本文介绍了如何在 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天全站免登陆