-------------------------------------------------------------------------------
Using OpenSSL for encryption and key generation
This command has a lot of features, from random data generators, password
hashing, encrypting data and files, hash checksums, through to encrypted SSL
connections to remote systems.
Help
http://www.madboa.com/geek/openssl/#encrypt-simple
Otherwise for a list of encryption types use...
openssl list-cipher-commands
-------------------------------------------------------------------------------
Encrypt a file
AES Encryption with Salt (very common)
# encrypt file.txt to file.enc using 256-bit AES in CBC mode
openssl enc -aes-256-cbc -in file.txt -out file.enc
# decrypt binary file.enc
openssl enc -d -aes-256-cbc -in file.enc -out file.txt
WARNING: This uses the fast PBKDF1.5 password to key function. It does not
use the slower more modern PBKDF2 method (see below). As such it is prone to
brute force dictionary attacks, even with salting. See "Password to Key"
below.
-------------------------------------------------------------------------------
Password in same pipeline
By including the password as part of the pipeline you avoid the need to place
the password on the command line, environment variable or reading it from
a TTY, or other file decriptor. Great for shell scripts.
Note the use of "echo -n" in encrypting, but NOT in decrypting!
Otherwise it you could get errors such as "wrong final block length"
or "error reading input file"
# encrypt
passwd="ThePassword"
secret="This is a Secret"
encrypted=`( echo "$passwd"; echo -n "$secret"; ) |
openssl enc -aes-256-cbc -pass stdin -base64`
# result
echo "$encrypted"
U2FsdGVkX1/KqnAoxyKIursXeqKuYYYCgayTASgQ/rcVjuOUdNLtWAeaIGb6AhLV
# decrypt
message=`( echo "$passwd"; echo "$encrypted"; ) |
openssl enc -d -aes-256-cbc -pass stdin -base64`
echo $message
This is a Secret
-------------------------------------------------------------------------------
Salt
Salt is turned on by default!
The 'salt' is a random 8 byte string that is stored with the encrypted file so
that every time you encrypt a file with a specific password or key the
resulting file will be different.
However it also adds 8 character 'file magic' to the start of the encrypted
output!
To identify the use of a salt, openssl also adds the file magic "Salted__" to
the start of the encrypted data stream.
For example...
echo "data" | openssl aes-256-cbc -pass pass:keyvar | dd bs=1 count=16
Salted__........
Where the '.' is the 8 byte salt charcaters, after that the encrypted data
blocks
Data length = 8 (magic) + 8 salted + 16 (one data block, padded)
--
No Salt
If -nosalt is used then no salt is added, but also no file magic identifier.
This is the (old method, using PBKDF1, just direct pure AES encryption of
data).
As such without salt a fixed password/file will always produce the same
encrypted result. In this case one block, or 16 bytes.
echo "data" | openssl aes-256-cbc -a -pass pass:keyvar -nosalt
YQl6Zg03yi87w54gUPba5g==
However this makes the encryption prone to rainbow table dictionary attacks.
WARNING: To decode a '-nosalt' encryption, you need -nosalt when decrypting.
-------------------------------------------------------------------------------
PBKDF2 - iterative password hashing
This not only needs a salt, but count of the number of times the hashing
function in applied. A large count will make brute force passward hashing
very difficult.
Only one hashing sequence is used, with both the Key and IV beting extracted
from the results.
This does not appear to be available from openssl command line. :-(
-------------------------------------------------------------------------------
Password to Encryption Key
OpenSSL generates the actual encryption key (generally a Hash and a IV) from
the user supplied password, plus some other 'public' data in a 'hashing
function'.
The other 'public' data is usally a 'salt' which is used to make
a pre-prepared 'dictionary' attack usless. This comes from some encryption
configuration data (along with the encryption method, data locations etc)
which is typically part of, or close to, the encrypted data.
For aes-128
Key = MD5(passwd + salt)
IV = MD5(Key + Password + Salt)
Note that this password hashing function is simple (and thus fast) It does not
provide any protection in the form of a slow variable hash.
For aes-256 the key size is 32 so a longer sequence is needed
Hash0 = ''
Hash1 = MD5(Hash0 + Password + Salt)
Hash2 = MD5(Hash1 + Password + Salt)
Hash3 = MD5(Hash2 + Password + Salt)
Hash4 = MD5(Hash3 + Password + Salt)
...
The hash is then split to generate the 'Key' and 'IV' needed to decrypt.
Key = Hash1 + Hash2
IV = Hash3
See EVP_BytesToKey() function
http://www.openssl.org/docs/crypto/EVP_BytesToKey.html
A different hash could be used, with the sequence continuing until
enough bits have been hashed to set both Key + IV in sequence.
The better function to use however is
PKCS5_PBKDF2_HMAC_SHA1()
which implements the newer iteritive hash function. This interates a couple
of thousand times (count given with salt) so the computer needs at least
a couple of seconds to convert the given ( Password + Salt + Count ), into
the ( Key + IV ). This makes brute force attacks very slow and time
consuming, making such attacks impractical.
While this function is in the openssl library, it is not in the openssl
command. However a trivial program "pbkdf2.c" can make the function avilable
to external scripting programs.
ASIDE:
PKCS5 Password based encryption #5 (also know as PBKDF1)
PBKDF2 is the iterative hashing method to derive Key and IV
HMAC-SHA1 hashing function used for PBKDF
-------------------------------------------------------------------------------
Passphrase handling in OpenSSL
From command line...
-pass pass:mySillyPassword
From file
-pass file:/path/to/secret/password.txt
From File descriptor
-pass fd:N
From stdin
-pass stdin
Only the last two methods can be deemed to be 'secure' from other users
on the machine it is run on. See including "password from pipeline" above
The third can be secure using named pipes, but only if the named pipe is
secure.
Watch out for newlines!
===============================================================================
Other functions of "openssl"
===============================================================================
Error Interpretation
from log...
sshd[31784]: error: RSA_public_decrypt failed:
error:0407006A:lib(4):func(112):reason(106)
look up
openssl errstr 0407006A
error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:
block type is not 01
The RSA_padding_add_PKCS1_type_1(3) manpage then says...
block methods for signatures
-------------------------------------------------------------------------------
Random Data Generation
# write 128 random bytes of base64-encoded data to stdout
openssl rand -base64 128
# write 1024 bytes of binary random data to a file
openssl rand -out random-data.bin 1024
# seed openssl with semi-random bytes from browser cache
cd $(find ~/.mozilla/firefox -type d -name Cache | head -n 1)
openssl rand -rand $(find . -type f -printf '%f:') -base64 1024
# get 32 bytes from /dev/urandom and base64 encode them
head -c 32 /dev/urandom | openssl enc -base64
-------------------------------------------------------------------------------
Checksums and Hashing
# This is exactly like "md5sum" but with different output
openssl dgst -md5 filename
MD5(filename)= 81eda7985e99d28acd6d286aa0e13e07
# This is exactly like "sha1sum" but with different output
openssl dgst -sha1 filename
SHA1(filename)= e4eabc78894e2c204d788521812497e021f45c08
You can also output the hash as -binary or -hex (default)
Unfortunateally you can not output it in base64. But you can pipe it
back into openssl to convert to base64
echo -n "$text" | openssl dgst -md5 -binary | openssl enc -base64
4cuww4ea+DRyRvEsVZqGtQ==
(the echo is a bash builtin, so from a script "text" is not visible in the
process list.
You can convert that into a 22 character random filename...
echo -n "text" | openssl dgst -sha1 -binary |
dd bs=1 skip=2 count=18 2>/dev/null |
openssl enc -base64 | tr '+/' ',-'
oIyrM,ccAsZR28g6R00yxnbq
This filename is similar to what use generated by EncFS but it is
NOT the same scheme that EncFS uses, which includes a checksum. :-(
NOTE: "openssl" command and "hashalot" does not implement iterative hashing as
per the PBKDF2 (RFC 2898) algorithm (Password-Based Key Derivation Function v2)
-------------------------------------------------------------------------------
Unix Password handling
# Generate the old UNIX des encrypted password
# Give previously encrypted password as -salt for testing
openssl passwd
# generate md5 encrypted password
openssl passwd -1
-------------------------------------------------------------------------------
SSL conection to a remote server
To talk to the wever via HTTPS using 'openssl'...
=======8 openssl s_client -connect www.ict.griffith.edu.au:443
CONNECTED(00000003)
...lots of output about server and its certificate...
---
HEAD / HTTP/1.0