Sign up ×
Information Security Stack Exchange is a question and answer site for information security professionals. It's 100% free, no registration required.

A large amount of files were encrypted by

    openssl enc -aes-256-cbc -pass pass:MYPASSWORD

Openssl should derive key+IV from passphrase. I'd like to know key+IV equivalent of that MYPASSWORD. Is that possible?

I know MYPASSWORD. I could decrypt and then re-encrypt with new known key+IV with:

    openssl enc -d -aes-256-cbc -pass pass:MYPASSWORD
    openssl enc -aes-256-cbc -K MYKEY -IV MYIV

But the problem is that the amount of data is quite large.

share|improve this question
Don't cross-post – CodesInChaos Jan 16 '13 at 10:17

2 Answers 2

up vote 26 down vote accepted

Usage of the openssl enc command-line option is described there. Below, I will answer your question, but don't forget to have a look at the last part of my text, where I take a look at what happens under the hood. It is... instructive.

OpenSSL uses a salted key derivation algorithm. The salt is a piece of random bytes which are generated when encrypting, and stored in the file header; upon decryption, the salt is retrieved from the header, and the key and IV are recomputed from the provided password and the salt value.

On the command-line, you can use the -P option (uppercase P) to print out the salt, key and IV, and then exit. You can also use the -p (lowercase P) to print out the salt, key and IV, and then proceed with the encryption. First try this out:

openssl enc -aes-256-cbc -pass pass:MYPASSWORD -P

If you run this command several times, you will notice that each invocation returns different values ! That's because, in the absence of the -d flag, openssl enc does encryption and generates a random salt each time. Since the salt varies, so do the key and IV. Thus, the -P flag is not very useful when encrypting; the -p flag, however, can be used. Let's try again; this time, we have the file foo_clear which we want to encrypt into foo_enc. Let's run this:

openssl enc -aes-256-cbc -pass pass:MYPASSWORD -p -in foo_clear -out foo_enc

This command will encrypt the file (thus creating foo_enc) and print out something like this:

iv =B9F128D827203729BE52A834CC0890B7

These values are the salt, key and IV which were actually used to encrypt the file.

If I want to get them back afterwards, I can use the -P flag in conjunction with the -d flag:

openssl enc -aes-256-cbc -pass pass:MYPASSWORD -d -P -in foo_enc

which will print out the same salt, key and IV than above, every time. How so ? That's because this time we are decrypting, so the header of foo_enc is read, and the salt retrieved. For a given salt value, derivation of the password into key and IV is deterministic.

Moreover, this key-and-IV retrieval is fast, even if the file is very long, because the -P flag prevents actual decryption; it reads the header, but stops there.

Alternatively, you can specify the salt value with the -S flag, or deactivate the salt altogether with -nosalt. Unsalted encryption is not recommended at all because it may allow speeding up password cracking with precomputed tables (the same password always yields the same key and IV). If you provide the salt value, then you become responsible for generating proper salts, i.e. trying to make them as unique as possible (in practice, you have to produce them randomly). It is preferable to let openssl handle that, since there is ample room for silent failures ("silent" meaning "weak and crackable, but the code still works so you do not detect the problem during your tests").

The encryption format used by OpenSSL is non-standard: it is "what OpenSSL does", and if all versions of OpenSSL tend to agree with each other, there is still no reference document which describes this format except OpenSSL source code. The header format is rather simple:

magic value (8 bytes): the bytes 53 61 6c 74 65 64 5f 5f
salt value (8 bytes)

Hence a fixed 16-byte header, beginning with the ASCII encoding of the string "Salted__", followed by the salt itself. That's all ! No indication of the encryption algorithm; you are supposed to keep track of that yourself.

The process by which the password and salt are turned into the key and IV is not documented, but a look at the source code shows that it calls the OpenSSL-specific EVP_BytesToKey() function, which uses a custom key derivation function with some repeated hashing. This is a non-standard and not-well vetted construct (!) which relies on the MD5 hash function of dubious reputation (!!); that function can be changed on the command-line with the undocumented -md flag (!!!); the "iteration count" is set by the enc command to 1 and cannot be changed (!!!!). This means that the first 16 bytes of the key will be equal to MD5(password||salt), and that's it.

This is quite weak ! Anybody who knows how to write code on a PC can try to crack such a scheme and will be able to "try" several dozens of millions of potential passwords per second (hundreds of millions will be achievable with a GPU). If you use "openssl enc", make sure your password has very high entropy ! (i.e. higher than usually recommended; aim for 80 bits, at least). Or, preferably, don't use it at all; instead, go for something more robust (GnuPG, when doing symmetric encryption for a password, uses a stronger KDF with many iterations of the underlying hash function).

share|improve this answer
brillant answer, thanks. – bluehallu Mar 29 '14 at 19:03
This is the best insight to how openssl aes-256-cbc works! – Xample Jan 22 at 23:25

Have you tried the -P option?

openssl enc -aes-256-cbc -pass pass:MYPASSWORD -P

iv =186DE986FC69F8E47ED692B24D940BED
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.