Tooleux

Derive a key and IV from a password and salt using OpenSSL's legacy EVP_BytesToKey KDF.

Runs in your browser. Nothing leaves your device.
Derive the key and IV used by OpenSSL enc from a password and salt. Legacy OpenSSL compatibility. Free, offline, runs entirely client-side. Read more Show less

What is EVP_BytesToKey?

EVP_BytesToKey is the key derivation function used by OpenSSL's enc command for password-based encryption. It was defined in the original 1995 OpenSSL and remained the default until OpenSSL 1.1.1 added PBKDF2 as an alternative. Many real-world encrypted files still use it.

The algorithm is simple: it repeatedly applies MD5 (or another digest) to a running chain of password and salt, concatenating the outputs until enough key and IV material is produced. It is much weaker than PBKDF2, scrypt, or Argon2, but it is what you need to decrypt legacy OpenSSL files.

When you need this

If you have a file encrypted with the old OpenSSL format, it starts with the ASCII bytes Salted__ followed by 8 bytes of salt. The key and IV for the actual cipher are derived from your password and that salt using EVP_BytesToKey.

To decrypt such a file, you extract the salt from the file, run this tool to get the key and IV, then use a cipher tool (AES, DES, etc.) with those raw bytes.

OpenSSL 3.x and later use PBKDF2 by default. If you encrypted with -pbkdf2 or with a recent OpenSSL, use the PBKDF2 tool instead.

How to use

Enter your password, enter the salt (8 bytes in hex or Base64), choose the hash, and set the key and IV lengths. The tool outputs the derived key and IV as hex.

Common combinations:

AES-256-CBC: key 32 bytes, IV 16 bytes, MD5 hash.

AES-128-CBC: key 16 bytes, IV 16 bytes, MD5 hash.

DES-EDE3-CBC: key 24 bytes, IV 8 bytes, MD5 hash.

OpenSSL 3.x with SHA-256: same lengths but hash = SHA-256.

About the salt

OpenSSL salts are 8 bytes. When you see a file starting with Salted__, the next 8 bytes are the salt. Everything after that is the ciphertext.

If no salt was used (the -nosalt flag), the salt is empty. That is insecure and rare; provide an empty salt field only if you are certain.

FAQ

Is EVP_BytesToKey secure?

No. It is weaker than PBKDF2 by a wide margin - it does not iterate enough to slow down brute force. It survives only because so much legacy data was encrypted with it. Use PBKDF2, scrypt, or Argon2 for anything new.

Why does my derivation not match OpenSSL?

Check three things: (1) the hash function - MD5 is the OpenSSL 1.1.1 default, SHA-256 is the OpenSSL 3.x default; (2) the salt is exactly 8 bytes; (3) the password includes any trailing whitespace and is byte-for-byte what you typed. Even a single extra character changes everything.

What is the difference between EVP_BytesToKey and PBKDF2?

PBKDF2 runs the hash function many thousands of times in a controlled way, which makes brute-force attacks much slower. EVP_BytesToKey runs the hash just enough times to fill the required key and IV, which for AES-256-CBC means about 3 iterations. That is 1000x weaker than a typical PBKDF2 configuration.

Can I get the key and IV from a Salted__ file without the password?

No. The salt is visible in the file, but the key derivation requires the password. Without it, the file cannot be decrypted except by brute force.

What key/IV length does my cipher need?

AES-128: key 16, IV 16. AES-192: key 24, IV 16. AES-256: key 32, IV 16. DES: key 8, IV 8. Triple DES: key 24, IV 8. Blowfish: key 16, IV 8. RC4: key 16, IV 0.

Does EVP_BytesToKey support SHA-256?

Yes, since OpenSSL 1.1.1 you can specify any digest. OpenSSL 3.x uses SHA-256 by default. If you used openssl enc -aes-256-cbc -pbkdf2, use PBKDF2 instead - it is a different algorithm.

Command line equivalent
# OpenSSL: extract the salt from a Salted__ file
head -c 16 encrypted.bin | xxd
# First 8 bytes: 53 61 6c 74 65 64 5f 5f  ("Salted__")
# Next 8 bytes: the salt

# OpenSSL: derive key+IV (OpenSSL 1.1.1)
openssl enc -aes-256-cbc -d -P -pass pass:yourpassword -S 0123456789abcdef
# Prints salt=... key=... iv=...

# Python with cryptography
python3 -c '
import hashlib
def evp_bytes_to_key(password, salt, key_len, iv_len, hash_fn=hashlib.md5):
    d = b""
    prev = b""
    while len(d) < key_len + iv_len:
        prev = hash_fn(prev + password + salt).digest()
        d += prev
    return d[:key_len], d[key_len:key_len+iv_len]
key, iv = evp_bytes_to_key(b"password", bytes.fromhex("0123456789abcdef"), 32, 16)
print(key.hex(), iv.hex())
'
Loads a test value into the form
Derived key and IV