10

What hash function does OpenSSL use to generate a key for AES-256? I can't find it anywhere in their documentation.

$ touch file
$ openssl aes-256-cbc -nosalt -P -in file

enter aes-256-cbc encryption password: (I type "a" and hit enter)
Verifying - enter aes-256-cbc encryption password: (I type "a" and hit enter)

key=0CC175B9C0F1B6A831C399E269772661CEC520EA51EA0A47E87295FA3245A605
iv =4FA92C5873672E20FB163A0BCB2BB4A4

Which hash algorithm generates the unsalted hash after key= on the second last line, for the input "a"?

mk12
  • 3,132
  • 5
  • 29
  • 34

3 Answers3

12

Fairly sure it's an SHA1 digest algorithm but in all honesty I can't say with 100% certainty.

And who would have thought that something designed to increase obtuseness would have obtuse instructions ;)

EDIT: This may not be helpful in your circumstances but I guess you could always know by doing

openssl enc -d -a -md sha1 -aes-256-cbc -nosalt -p 
Snesticle
  • 966
  • 1
  • 8
  • 15
  • I have determined that it uses MD5 by default, as when I use your command (sidenote: none of those options are documented in the mage page...) with `md5` instead of `sha1`, I get the same results as I originally posted. The question is, how does it get 256 bits from MD5 (a 128-bit hashing algorithm)? – mk12 Sep 08 '12 at 00:30
  • One way this is done is by concatenating two disparate MD5's in binary form which results in a true 256 bit key. There are a few other methods for this as well. You might check out the php package "md5_base64". Even if you're not a php guy, the docs are pretty informative. – Snesticle Sep 08 '12 at 01:20
6

It's a concatenation of two MD5 hashes.

It's derived like this:

128bit_Key = MD5(Passphrase + Salt)
256bit_Key = 128bit_Key + MD5(128bit_Key + Passphrase + Salt)

You can check this by doing:

$ echo Testing > file
$ openssl enc -aes-256-cbc -p -in file -out file.aes -salt
: enter aes-256-cbc encryption password: abc
: Verifying - enter aes-256-cbc encryption password: abc
: salt=3025373CA0530C93
: key=E165475C6D8B9DD0B696EE2A37D7176DFDF4D7B510406648E70BAE8E80493E5E
: iv =B030394C16C76C7A94DC22FDDB6B0744
$ perl -e 'print pack "H*", "3025373CA0530C93"' > salt
$ echo -n abc > passphrase
$ cat passphrase > key.128.tmp
$ cat salt >> key.128.tmp
$ md5sum key.128.tmp 
: e165475c6d8b9dd0b696ee2a37d7176d  key.128.tmp
$ perl -e 'print pack "H*", "e165475c6d8b9dd0b696ee2a37d7176d"' > key.128
$ cat key.128 > key.256.tmp
$ cat passphrase >> key.256.tmp
$ cat salt >> key.256.tmp
$ md5sum key.256.tmp 
: fdf4d7b510406648e70bae8e80493e5e  key.256.tmp

Notice how both MD5's of 'key.128.tmp' and 'key.256.tmp' concatenated together form the same key as output at the initial command.

user3281907
  • 61
  • 1
  • 3
  • And if you do a third iteration you'll get the IV. This case is convenient because the key and data=IV sizes (256 and 128 bits) are both exact multiples of the hash output; in general you concatenate the hash outputs and take the first K bits for the key and the next D bits for the IV. – dave_thompson_085 Sep 10 '15 at 21:52
  • 1
    update: the default used to be md5, but as of 1.1.0 in 2016 it is sha256. Full details at https://crypto.stackexchange.com/questions/3298/is-there-a-standard-for-openssl-interoperable-aes-encryption – dave_thompson_085 Dec 10 '17 at 07:33
2

OpenSSL uses AES with SHA1.

If you wish to examine better-written source than OpenSSL, have a look at the article
C++ class that interfaces to OpenSSL ciphers.

The article includes very simple source code that :

allows you to encrypt and decrypt files or strings using the OpenSSL AES-256-CBC cipher and SHA1 digest algorithms. It is interoperable with the openssl command line tool which makes it a good introduction to using OpenSSL for ciphers.

harrymc
  • 455,459
  • 31
  • 526
  • 924