For example, the command:
openssl enc -aes-256-cbc -a -in test.txt -k pinkrhino -nosalt -p -out openssl_output.txt
outputs something like:
key = 33D890D33F91D52FC9B405A0DDA65336C3C4B557A3D79FE69AB674BE82C5C3D2
iv = 677C95C475C0E057B739750748608A49
How is that key generated? (C code as an answer would be too awesome to ask for :) ) Also, how is the iv generated?
Looks like some kind of hex to me.
OpenSSL uses the function EVP_BytesToKey. You can find the call to it in apps/enc.c
. The enc
utility used to use the MD5 digest by default in the Key Derivation Algorithm (KDF) if you didn't specify a different digest with the -md
argument. Now it uses SHA-256 by default. Here's a working example using MD5:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
int main(int argc, char *argv[])
{
const EVP_CIPHER *cipher;
const EVP_MD *dgst = NULL;
unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
const char *password = "password";
const unsigned char *salt = NULL;
int i;
OpenSSL_add_all_algorithms();
cipher = EVP_get_cipherbyname("aes-256-cbc");
if(!cipher) { fprintf(stderr, "no such cipher\n"); return 1; }
dgst=EVP_get_digestbyname("md5");
if(!dgst) { fprintf(stderr, "no such digest\n"); return 1; }
if(!EVP_BytesToKey(cipher, dgst, salt,
(unsigned char *) password,
strlen(password), 1, key, iv))
{
fprintf(stderr, "EVP_BytesToKey failed\n");
return 1;
}
printf("Key: "); for(i=0; i<cipher->key_len; ++i) { printf("%02x", key[i]); } printf("\n");
printf("IV: "); for(i=0; i<cipher->iv_len; ++i) { printf("%02x", iv[i]); } printf("\n");
return 0;
}
Example usage:
gcc b2k.c -o b2k -lcrypto -g
./b2k
Key: 5f4dcc3b5aa765d61d8327deb882cf992b95990a9151374abd8ff8c5a7a0fe08
IV: b7b4372cdfbcb3d16a2631b59b509e94
Which generates the same key as this OpenSSL command line:
openssl enc -aes-256-cbc -k password -nosalt -p < /dev/null
key=5F4DCC3B5AA765D61D8327DEB882CF992B95990A9151374ABD8FF8C5A7A0FE08
iv =B7B4372CDFBCB3D16A2631B59B509E94
OpenSSL 1.1.0c changed the digest algorithm used in some internal components. Formerly, MD5 was used, and 1.1.0 switched to SHA256. Be careful the change is not affecting you in both EVP_BytesToKey
and commands like openssl enc
.