如何解密使用openssl加密的python文件

时间:2018-11-18 08:23:53

标签: python encryption openssl

我通过以下命令使用988888813加密了文件

openssl

如何使用python Crypto软件包解密文件。我尝试了下面的方法,但是没有用。

cat input.txt
hello world
openssl aes-256-cbc -pass pass:'00112233445566778899aabbccddeeff' -iv a2a8a78be66075c94ca5be53c8865251 -nosalt -base64 -in input.txt -out output.txt
cat output.txt
pt7DqtAwtTjPbTlzVApucQ==

我需要一种使用openssl aes-256-cbc密码加密文件并在python中解密的方法

1 个答案:

答案 0 :(得分:3)

密码不是密钥。 Openssl使用EVP_BytesToKey从密码和密码中创建适当的密钥(如果需要,可以使用&IV。)。

正如James K Polk在评论中提到的那样,您可以使用-P(或-p)选项告诉Openssl打印密钥(十六进制),然后将其传递给Crypto.Cipher。另外,您可以在Python中实现EVP_BytesToKey,如下所示。这是EVP_BytesToKey的简化版本,不使用盐,并且count arg的默认值为1。

正如EVP_BytesToKey文档所述,这是一个相当弱的密码派生功能。正如hashlib docs所述,现代密码派生通常执行成千上万的哈希,使密码哈希攻击非常缓慢。

我们还需要一个函数,用于从解密的数据字节中删除PKCS7 padding。下面的unpad函数仅假设填充数据有效。在真实软件中,unpad函数必须验证填充数据是否有效,以防止基于填充的攻击。我的unpad函数还假定数据已被编码为UTF-8字节,并将未填充的数据解码为文本。

from __future__ import print_function
from Crypto.Cipher import AES
from base64 import b64decode
from hashlib import md5

def evp_simple(data):
    out = ''
    while len(out) < 32:
        out += md5(out + data).digest()
    return out[:32]

def unpad(s):
    offset = ord(s[-1])
    return s[:-offset].decode('utf-8')

iv = 'a2a8a78be66075c94ca5be53c8865251'.decode('hex')
passwd = '00112233445566778899aabbccddeeff'
key = evp_simple(passwd)
print('key', key.encode('hex'))

aes = AES.new(key, AES.MODE_CBC, IV=iv)

data = b64decode('pt7DqtAwtTjPbTlzVApucQ==')

raw = aes.decrypt(data)
print(repr(raw), len(raw))
plain = unpad(raw)
print(repr(plain), len(plain))

输出

key b4377f7babf2991b7d6983c4d3e19cd4dd37e31af1c9c689ca22e90e365be18b
'hello world\n\x04\x04\x04\x04' 16
u'hello world\n' 12

该代码将无法在Python 3上运行,因此这是Python 3版本。

from Crypto.Cipher import AES
from base64 import b64decode
from hashlib import md5

def evp_simple(data):
    out = b''
    while len(out) < 32:
        out += md5(out + data).digest()
    return out[:32]

def unpad(s):
    offset = s[-1]
    return s[:-offset].decode('utf-8')

iv = bytes.fromhex('a2a8a78be66075c94ca5be53c8865251')
passwd = b'00112233445566778899aabbccddeeff'
key = evp_simple(passwd)

aes = AES.new(key, AES.MODE_CBC, IV=iv)

data = b64decode('pt7DqtAwtTjPbTlzVApucQ==')

raw = aes.decrypt(data)
print(repr(raw), len(raw))
plain = unpad(raw)
print(repr(plain), len(plain))

输出

b'hello world\n\x04\x04\x04\x04' 16
'hello world\n' 12