How To Decrypt A File In Python Which Was Encrypted Using Openssl
I encrypted a file using openssl
using the below command
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==
How can i decrypt the file using python Crypto package. I tried the below and it didn't work.
>>> from Crypto.Cipher import AES
>>> from base64 import b64decode
>>> with open('output.txt') as f:
... aes = AES.new('00112233445566778899aabbccddeeff', AES.MODE_CBC, IV='a2a8a78be66075c94ca5be53c8865251'.decode('hex'))
... print(aes.decrypt(b64decode(f.read())))
...
L�|�L ��O�*$&9�
I need a way to encrypt a file using openssl aes-256-cbc cipher and decrypt in python
Answer
The password is not the key. Openssl uses EVP_BytesToKey
to create an appropriate key (& IV, if necessary) from the password and the salt.
As James K Polk mentions in a comment, you can use the -P (or -p) option to tell Openssl to print the key (in hex ), which you can then pass to Crypto.Cipher. Alternatively, you can implement EVP_BytesToKey
in Python, as shown below. This is a simplified version of EVP_BytesToKey
that uses no salt, and the default value of 1 for the count
arg.
As the EVP_BytesToKey
docs state, this is a rather weak password derivation function. As the hashlib docs mention, modern password derivation normally performs hundreds of thousands of hashes to make password hashing attacks very slow.
We also need a function to remove the PKCS7 padding from the decrypted data bytes. The unpad
function below simply assumes that the padding data is valid. In real software the unpad
function must verify that the padded data is valid to prevent padding-based attacks. My unpad
function also assumes the data has been encoded as UTF-8 bytes and decodes the unpadded data to text.
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))
output
key b4377f7babf2991b7d6983c4d3e19cd4dd37e31af1c9c689ca22e90e365be18b
'hello world\n\x04\x04\x04\x04' 16
u'hello world\n' 12
That code will not run on Python 3, so here's a Python 3 version.
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))
output
b'hello world\n\x04\x04\x04\x04' 16
'hello world\n' 12
Related Questions
- → What are the pluses/minuses of different ways to configure GPIOs on the Beaglebone Black?
- → Django, code inside <script> tag doesn't work in a template
- → React - Django webpack config with dynamic 'output'
- → GAE Python app - Does URL matter for SEO?
- → Put a Rendered Django Template in Json along with some other items
- → session disappears when request is sent from fetch
- → Python Shopify API output formatted datetime string in django template
- → Can't turn off Javascript using Selenium
- → WebDriver click() vs JavaScript click()
- → Shopify app: adding a new shipping address via webhook
- → Shopify + Python library: how to create new shipping address
- → shopify python api: how do add new assets to published theme?
- → Access 'HTTP_X_SHOPIFY_SHOP_API_CALL_LIMIT' with Python Shopify Module