Add a salt to the key derivation using the 'enc' program.

This commit is contained in:
Dr. Stephen Henson 1999-11-16 02:49:25 +00:00
parent e947f39689
commit fd699ac55f
3 changed files with 121 additions and 45 deletions

View file

@ -4,6 +4,11 @@
Changes between 0.9.4 and 0.9.5 [xx XXX 1999]
*) Add a salt to the key derivation routines in enc.c. This
forms the first 8 bytes of the encrypted file. Also add a
-S option to allow a salt to be input on the command line.
[Steve Henson]
*) New function X509_cmp(). Oddly enough there wasn't a function
to compare two certificates. We do this by working out the SHA1
hash and comparing that. X509_cmp() will be needed by the trust

View file

@ -65,6 +65,7 @@
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/rand.h>
#ifndef NO_MD5
#include <openssl/md5.h>
#endif
@ -86,10 +87,11 @@ int MAIN(int argc, char **argv)
int bsize=BSIZE,verbose=0;
int ret=1,inl;
unsigned char key[24],iv[MD5_DIGEST_LENGTH];
unsigned char salt[PKCS5_SALT_LEN];
char *str=NULL;
char *hkey=NULL,*hiv=NULL;
char *hkey=NULL,*hiv=NULL,*hsalt = NULL;
int enc=1,printkey=0,i,base64=0;
int debug=0,olb64=0;
int debug=0,olb64=0,nosalt=1;
const EVP_CIPHER *cipher=NULL,*c;
char *inf=NULL,*outf=NULL;
BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
@ -136,8 +138,11 @@ int MAIN(int argc, char **argv)
printkey=1;
else if (strcmp(*argv,"-v") == 0)
verbose=1;
else if ((strcmp(*argv,"-debug") == 0) ||
(strcmp(*argv,"-d") == 0))
else if (strcmp(*argv,"-salt") == 0)
nosalt=0;
else if (strcmp(*argv,"-nosalt") == 0)
nosalt=1;
else if (strcmp(*argv,"-debug") == 0)
debug=1;
else if (strcmp(*argv,"-P") == 0)
printkey=2;
@ -194,6 +199,11 @@ int MAIN(int argc, char **argv)
if (--argc < 1) goto bad;
hkey= *(++argv);
}
else if (strcmp(*argv,"-S") == 0)
{
if (--argc < 1) goto bad;
hsalt= *(++argv);
}
else if (strcmp(*argv,"-iv") == 0)
{
if (--argc < 1) goto bad;
@ -386,11 +396,73 @@ bad:
}
}
if (outf == NULL)
BIO_set_fp(out,stdout,BIO_NOCLOSE);
else
{
if (BIO_write_filename(out,outf) <= 0)
{
perror(outf);
goto end;
}
}
rbio=in;
wbio=out;
if (base64)
{
if ((b64=BIO_new(BIO_f_base64())) == NULL)
goto end;
if (debug)
{
BIO_set_callback(b64,BIO_debug_callback);
BIO_set_callback_arg(b64,bio_err);
}
if (olb64)
BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
if (enc)
wbio=BIO_push(b64,wbio);
else
rbio=BIO_push(b64,rbio);
}
if (cipher != NULL)
{
if (str != NULL)
{
EVP_BytesToKey(cipher,EVP_md5(),NULL,
/* Salt handling: if encrypting generate a salt and
* write to output BIO. If decrypting read salt from
* input BIO.
*/
unsigned char *sptr;
if(nosalt) sptr = NULL;
else {
if(enc) {
if(hsalt) {
if(!set_hex(hsalt,salt,PKCS5_SALT_LEN)) {
BIO_printf(bio_err,
"invalid hex salt value\n");
goto end;
}
} else RAND_bytes(salt, PKCS5_SALT_LEN);
/* If -P option then don't bother writing */
if((printkey != 2) && (BIO_write(wbio,
(unsigned char *) salt,
PKCS5_SALT_LEN) != PKCS5_SALT_LEN)) {
BIO_printf(bio_err,"error writing output file\n");
goto end;
}
} else if(BIO_read(rbio, (unsigned char *)salt,
PKCS5_SALT_LEN) != PKCS5_SALT_LEN) {
BIO_printf(bio_err,"error reading input file\n");
goto end;
}
sptr = salt;
}
EVP_BytesToKey(cipher,EVP_md5(),sptr,
(unsigned char *)str,
strlen(str),1,key,iv);
/* zero the complete buffer or the string
@ -424,6 +496,13 @@ bad:
if (printkey)
{
if (!nosalt)
{
printf("salt=");
for (i=0; i<PKCS5_SALT_LEN; i++)
printf("%02X",salt[i]);
printf("\n");
}
if (cipher->key_len > 0)
{
printf("key=");
@ -446,38 +525,6 @@ bad:
}
}
if (outf == NULL)
BIO_set_fp(out,stdout,BIO_NOCLOSE);
else
{
if (BIO_write_filename(out,outf) <= 0)
{
perror(outf);
goto end;
}
}
rbio=in;
wbio=out;
if (base64)
{
if ((b64=BIO_new(BIO_f_base64())) == NULL)
goto end;
if (debug)
{
BIO_set_callback(b64,BIO_debug_callback);
BIO_set_callback_arg(b64,bio_err);
}
if (olb64)
BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
if (enc)
wbio=BIO_push(b64,wbio);
else
rbio=BIO_push(b64,rbio);
}
/* Only encrypt/decrypt as we write the file */
if (benc != NULL)
wbio=BIO_push(benc,wbio);

View file

@ -40,6 +40,18 @@ the input filename, standard input by default.
the output filename, standard output by default.
=item B<-salt>
use a salt in the key derivation routines. This option should B<ALWAYS>
be used unless compatability with previous versions of OpenSSL or SSLeay
is required. This option is only present on OpenSSL versions 0.9.5 or
above.
=item B<-nosalt>
don't use a salt in the key derivation routines. This is the default for
compatability with previous versions of OpenSSL and SSLeay.
=item B<-e>
encrypt the input data: this is the default.
@ -66,6 +78,11 @@ the password to derive the key from.
read the password to derive the key from the first line of B<filename>
=item B<-S salt>
the actual salt to use: this must be represented as a string comprised only
of hex digits.
=item B<-K key>
the actual key to use: this must be represented as a string comprised only
@ -102,6 +119,16 @@ B<openssl enc -ciphername>.
A password will be prompted for to derive the key and IV if necessary.
The B<-salt> option should B<ALWAYS> be used unless you want compatability
with previous versions of OpenSSL and SSLeay.
Without the B<-salt> option it is possible to perform efficient dictionary
attacks on the password and to attack stream cipher encrypted data. The reason
for this is that without the salt the same password always generates the same
encryption key. When the salt is being used the first eight bytes of the
encrypted data are reserved for the salt: it is generated at random when
encrypting a file and read from the encrypted file when it is decrypted.
Some of the ciphers do not have large keys and others have security
implications if not used correctly. A beginner is advised to just use
a strong block cipher in CBC mode such as bf or des3.
@ -187,20 +214,20 @@ Decode the same file
Encrypt a file using triple DES in CBC mode using a prompted password:
openssl des3 -in file.txt -out file.des3
openssl des3 -salt -in file.txt -out file.des3
Decrypt a file using a supplied password:
openssl des3 -d -in file.des3 -out file.txt -k mypassword
openssl des3 -d -salt -in file.des3 -out file.txt -k mypassword
Encrypt a file then base64 encode it (so it can be sent via mail for example)
using Blowfish in CBC mode:
openssl bf -a -in file.txt -out file.bf
openssl bf -a -salt -in file.txt -out file.bf
Base64 decode a file then decrypt it:
openssl bf -d -a -in file.bf -out file.txt
openssl bf -d -salt -a -in file.bf -out file.txt
Decrypt some data using a supplied 40 bit RC4 key:
@ -210,10 +237,7 @@ Decrypt some data using a supplied 40 bit RC4 key:
The B<-A> option when used with large files doesn't work properly.
The key derivation algorithm used is compatible with the SSLeay algorithm. It
is not very good: it uses unsalted MD5.
There should be an option to allow a salt or iteration count to be included.
There should be an option to allow an iteration count to be included.
Like the EVP library the B<enc> program only supports a fixed number of
algorithms with certain parameters. So if, for example, you want to use RC2