The OpenSSL command line interface is called by forking the process and redirecting the input/output streams to pipes to communicate with the parent process, which limits publisher application use to UNIX like systems.
While implementing encryption with the CLI, I found a bug in OpenSSL key and IV generation. When you call openssl enc -aes-256-cbc -P -nosalt -pass stdin you pass in the password through standard input to generate the AES-256 key and IV. When you pass in random bytes, for example from head -c 16 /dev/random, there is a possibility that most or all of the random bytes will be ignored. The key derivation function reads the password in as a null terminated string, so as soon as the null byte is passed in, it stops reading the data. Therefore if one of the first few bytes is the null byte, the key and IV generated won't have much entropy. For example,
If you pass in an ASCII '5' (0x35), a null byte, followed by any data.
openssl enc -aes-256-cbc -P -nosalt -pass stdin
key=
iv =
The output will be the same as if you just passed in an ASCII '5'.
openssl enc -aes-256-cbc -P -nosalt -pass pass:5
key=
iv =
This effectively reduces the key space of the resulting key and IV to 256^n, where n is the location of the first null byte. An attacker with 2^16 entries containing keys generated from 0x0000 to 0xffff can break any password with a null byte in the first 3 bytes. Assuming the password passed in is uniform random bytes, about 2/256 passwords will be in the attackers table of 2^16 elements, which means that about 1% of passwords will be incredibly weak. Adding a salt doesn't mitigate the risk either, since the salt isn't secret information.