enc does password-based encryption (PBE) by default. This means the key, and IV if applicable which it is for CBC, is derived from the 'password' input by a Password-Based Key Derivation Function (PBKDF); the key is NOT the same as the input. And it uses a particularly poor PBKDF; for details see my attempt at a canonical. Further, the default hash in the PBKDF has changed, and you don't specify which OpenSSL release you use(d) -- but the
rand command you posted is an invalid form that was accidentally accepted by the old ad-hoc command parser and is rejected by the standardized parser in 1.1.0 up, so your release must be one that used MD5 for the
Incidentally this means most of the entropy in your
rand 64 was wasted; the MD5-based PBKDF cuts the entropy to 128 bits (or very slightly less, for technical reasons), and the extra cost of using AES-256 instead of AES-128 also is wasted and doesn't add anything to security. Using 1.1.0 up, or specifying
-md sha256, would avoid this specific problem, although there is really no point in using PBKDF/PBE at all for a fully random 'password'.
It happens that nodejs' older (and deprecated)
createCipheriv) uses almost the same poor PBKDF as older OpenSSL
enc: EVP_BytesToKey with MD5 and 1 iteration, but with no salt, which differs from the OpenSSL default and makes the PBKDF even weaker -- but that doesn't matter for a random 'password'.
If you want or need to be compatible with exactly that
openssl enc command, you'll have to code the equivalent of EVP_BytesToKey (for 1 iteration, which is fairly easy), and use
createCipheriv with the resulting (derived) key and IV, plus write OpenSSL's
Salted__ + salt header. See https://stackoverflow.com/questions/50181685/nodejs-createcipheriv-like-openssl for one example.
If it's enough to be compatible with
enc -nosalt on older releases (and
enc -nosalt -md md5 on all releases), you can just use
createCipher with the password, which must be printable chars e.g. hex as you did in your first example.
enc can encrypt and decrypt with 'raw' key and IV, not password-based. Since your key is fully random that's secure. If that is sufficient, just use
createCipheriv with a suitable key and IV. If you reuse a key it is vital the IV be unique (for CTR or OFB) and unpredictable (for CBC and CFB) for each use of a key, but if you use a different key every time it doesn't really matter what the IV is and you can even use a constant (such as all-zeros, which is convenient on the
enc side). Pass the key and IV in hex to the
-K (uppercase!) and
-iv. Note OpenSSL can't itself read these from files, like
-pass file: or
-kfile for a password, but in most Unix shells you can use file contents in an option like
openssl enc -aes-256-cbc -d -K $(cat key_hex_file) -iv $(cat iv_hex_file)
openssl enc -aes-256-cbc -d -K $(xxd -p key_bin_file) -iv $(xxd -p iv_bin_file)
# (in most cases it is necessary or prudent to doublequote "$(cmd)"
# but here the output is _only_ hex chars so not needed if sane IFS)
Meta PS: we have lots of other Qs about nodejs crypto, and about OpenSSL enc, but I couldn't find a good dupe for the combination.