EVP_BytesToKey implementation in other languages: Python, Node.js
source link: https://gist.github.com/tly1980/b6c2cc10bb35cb4446fb6ccf5ee5efbc
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
EVP_BytesToKey implementation in other languages
Instantly share code, notes, and snippets.
https://security.stackexchange.com/questions/29106/openssl-recover-key-and-iv-by-passphrase
Following code steal from [Simple python functions that provide openssl -aes-256-cbc compatible encrypt/decrypt] (http://joelinoff.com/blog/?p=885)
# ================================================================
# get_key_and_iv
# ================================================================
def get_key_and_iv(password, salt, klen=32, ilen=16, msgdgst='md5'):
'''
Derive the key and the IV from the given password and salt.
This is a niftier implementation than my direct transliteration of
the C++ code although I modified to support different digests.
CITATION: http://stackoverflow.com/questions/13907841/implement-openssl-aes-encryption-in-python
@param password The password to use as the seed.
@param salt The salt.
@param klen The key length.
@param ilen The initialization vector length.
@param msgdgst The message digest algorithm to use.
'''
# equivalent to:
# from hashlib import <mdi> as mdf
# from hashlib import md5 as mdf
# from hashlib import sha512 as mdf
mdf = getattr(__import__('hashlib', fromlist=[msgdgst]), msgdgst)
password = password.encode('ascii', 'ignore') # convert to ASCII
try:
maxlen = klen + ilen
keyiv = mdf(password + salt).digest()
tmp = [keyiv]
while len(tmp) < maxlen:
tmp.append( mdf(tmp[-1] + password + salt).digest() )
keyiv += tmp[-1] # append the last byte
key = keyiv[:klen]
iv = keyiv[klen:klen+ilen]
return key, iv
except UnicodeDecodeError:
return None, None
The decent implementation from the discussion.
import hashlib, binascii
from passlib.utils.pbkdf2 import pbkdf1
def hasher(algo, data):
hashes = {'md5': hashlib.md5, 'sha256': hashlib.sha256,
'sha512': hashlib.sha512}
h = hashes[algo]()
h.update(data)
return h.digest()
# pwd and salt must be bytes objects
def openssl_kdf(algo, pwd, salt, key_size, iv_size):
if algo == 'md5':
temp = pbkdf1(pwd, salt, 1, 16, 'md5')
else:
temp = b''
fd = temp
while len(fd) < key_size + iv_size:
temp = hasher(algo, temp + pwd + salt)
fd += temp
key = fd[0:key_size]
iv = fd[key_size:key_size+iv_size]
print('salt=' + binascii.hexlify(salt).decode('ascii').upper())
print('key=' + binascii.hexlify(key).decode('ascii').upper())
print('iv=' + binascii.hexlify(iv).decode('ascii').upper())
return key, iv
openssl_kdf('md5', b'test', b'\xF6\x81\x8C\xAE\x13\x18\x72\xBD', 32, 16)
generates the same output as:
openssl enc -aes-256-cbc -P -pass pass:test -S F6818CAE131872BD
openssl_kdf('sha256', b'test', b'\xF6\x81\x8C\xAE\x13\x18\x72\xBD', 32, 16)
generates the same output as:
openssl enc -aes-256-cbc -P -pass pass:test -S F6818CAE131872BD -md SHA256
A nodes.js implementation with MD5 only https://github.com/crypto-browserify/EVP_BytesToKey/blob/master/index.js
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK