OpenSSL 3DES encrytion parameters

encryptionopenssl

Suppose that I want to encrypt a text with the TripleDES algorithm in CBC mode, I have two choices.

1- An online tool, Like this

2- OpenSSL tool.

In the Online tool, I enter the Text, the KEY, and the IV.

In the OpenSSL, I enter the below command :

OpenSSL> des-ede3-cbc -in MyText.txt -K <KEY> -iv <IV>


but what happens when I use the below command:

OpenSSL> des-ede3-cbc -in Mytext.txt

First question: I want to know, is the KEY made up of the password that I entered in the two next lines? Based on what algorithm will it create the key?

If someone has only a password, can they decrypt my encrypted text?

Second question: What is Salt parameter!? what is the difference between an encryption command that uses -nosalt and one that doesn't?

Third question: When using -base64, is the output in base64 form? When I don't use this parameter, what is the format of the output?


Update:
Forth question: what do we need to decrypt an encrypted text? only password? both of IV and KEY? or all of them?

Fifth question:

I enter "1" as the password in openssl commandline. and then you this online tool and create MD5 hash of "1". As you see in the below picture, the first two bye of 3DES KEY is equal to MD5 hashing of the password that I entered. I want to know what is the last byte in the key? how it create?

And If someone have only Password,how can he decrypt my Encrypted text?

enter image description here

Best Answer

  1. The Key and IV are derived from the password you specify, using an OpenSSL-specific algorithm that the OpenSSL team is not proud of. They keep it around for backward compatibility's sake, but they recommend that you use better password-based key derivation functions, such as PKCS's PBKDF2.

OpenSSL's bespoke key derivation algorithm is in the function EVP_BytesToKey(3).

Key:

-K key the actual key to use: this must be represented as a string comprised only of hex digits.

IV:

In cryptography, an initialization vector (IV) or starting variable (SV)[1] is a fixed-size input to a cryptographic primitive that is typically required to be random or pseudorandom.

So the IV is additional input used to encrypt the file. It is not the key (I guess it's just terminology).

2 A salt is an additional (prefix) to the key you specify. (see Wikipedia. It makes it impossible to use rainbow tables or precalculated hash tables on your key. The salt is usually stored unencrypted.

3 The output will be binary and will quite likely contain non-printable characters. Your terminal emulator will try to render those byte values as printable characters in its default character encoding and typeface, but they will probably look like "garbage text" and not be safe for copy/paste, FTP or email.

4 To decrypt an encrypted text, you need the Key and IV. If you don't have one or both of those, and the ones you're missing were derived from the Password, then if you have the Password, you can re-derive they missing Key and/or IV from the Password. You don't need the Salt, because you already have it; it's pre-pended to the beginning of the encrypted text. The Salt isn't really a secret, it's just a way to foil pre-computed hash tables and rainbow tables.

5 As defined in EVP_BytesToKey(3), if you use a password of "1" and --nosalt, the first 16 Bytes of your Key will be:

md5( D_0 || password || salt)

(note that in this context, || means concatenation, not logical or)

which is equivalent to

md5 ( `null` || "1" || `null`)

which is equivalent to

md5("1")

Which turns out to be

0xc4ca4238a0b923820dcc509a6f75849b

This value is what the man page calls D_1.

The remaining needed bytes of the Key and IV are generated like this:

md5( D_1 || password || salt)

which is equivalent to

md5( 0xC4CA4238A0B923820DCC509A6F75849B || "1" || `null` )

which is equivalent to

md5( 0xC4CA4238A0B923820DCC509A6F75849B31 )

(note that the ASCII "1" becomes 0x31 concatenated at the end of the D_1 value)

which turns out to be:

0x7976c7161415c830816dd4068a1d9a52

which is what that man page calls D_2.

The Key only needs 8 more bytes than D_1 already proved, so it takes the first 8 bytes of D_2 and becomes:

Key: C4CA4238A0B923820DCC509A6F75849B7976c7161415c830

The IV only needs 8 bytes, and since there are 8 unused bytes from D_2, they become the IV:

IV: 816dd4068a1d9a52

Here's a command-line to generate D_1, the first 16 bytes of the Key (given your example of password "1" and --nosalt):

echo -n "1" | openssl md5

Here's a command-line to generate D_2, the remaining 8 bytes of the Key, plus all 8 bytes of the IV (again, given your example inputs):

echo -n "$(echo -n "1" | openssl md5 -binary)1" | md5

This works by taking the output of D_1 (making sure to keep it in binary rather than translating it into ASCII-encoded hex digits), appending "1" (0x31) to it, and taking the md5 of that.

Related Question