3

I'm playing around with openssl command line to verify my understanding on block cipher mode.

I read that ECB block cipher mode always encrypt the same text to the same output. AES operates on 16 bytes block, independently on the key length while DES operates on 8 byte blocks.

So I tried the following examples expecting the same block in the output to be repeated twice, but that's not the case.

➜ echo -n "1234567890abcdef1234567890abcdef" |  openssl enc -e -aes-256-ecb | hexdump
enter aes-256-ecb encryption password:
Verifying - enter aes-256-ecb encryption password:
0000000 53 61 6c 74 65 64 5f 5f 03 9a 3d 27 b9 9b f2 c6
0000010 c5 e3 3d 77 ca 4f df aa 90 aa d1 b8 22 04 43 c3
*
0000030 75 c8 72 0c 54 33 30 73 0a f1 8d 5a 17 f2 64 de
0000040
➜ echo -n "12345678123456781234567812345678" |  openssl enc -e -des-ecb | hexdump                                                                
enter des-ecb encryption password:
Verifying - enter des-ecb encryption password:
0000000 53 61 6c 74 65 64 5f 5f 64 00 a6 ee 5c f5 a0 b8
0000010 c3 3c 57 65 4a 0c 37 81 c3 3c 57 65 4a 0c 37 81
*
0000030 9e 37 2c cf f9 27 74 fb                        
0000038

In the first example, the input is 32 bytes, and the first 16 bytes are the same as the last 16 bytes, which is the block size of AES. Given that I'm using ECB, I'd expect the same ciphertext in the output twice.

In the second example, the input also 32 bytes, and it's composed of the same 8 bytes (1-8), which is the block size of DES. Same assumption here

Not only I don't see a repetition, but I noticed that the first 8 bytes are the same between AES and DES.

Also, why does openssl asks for a password? It that used to generate the key?

Thanks a lot.

EDIT: clarified the example

emitrax
  • 133
  • 4

2 Answers2

7

The reason that you are seeing different outputs each time you use openssl enc -e -aes-256-ecb to encrypt the same plaintext with the same password is because openssl is using a different random salt each time you run it. The salt is combined with the password to derive the encryption key, which is fed into the aes-256-ecb algorithm.

If you specify the encryption key directly (instead of deriving an encryption key from a password as you are doing), using the -K option, you should see that openssl enc -e -aes-256-ecb produces the same result each time given the same plaintext and same key. For example, the command below produces the same output each time you run it:

echo -n "1234567890abcdef1234567890abcdef" |  openssl enc -e -aes-256-ecb -K dba50aff3f87d7d41429f9b59380ac539cc62a89adfdefcd5157015e0e768382 | hexdump

When specifying a password instead of a key with openssl enc, the first eight bytes in the output are the ascii codes for the string 'Salted__'. openssl puts this in the output to denote that the next eight bytes are the salt. You can verify this by running echo -n '53616c7465645f5f' | xxd -p -r. This produces Salted__.

For more info on all of the above, see Where is the salt on the OpenSSL AES encryption?.

mti2935
  • 21,098
  • 2
  • 47
  • 66
  • Thanks a lot. This answer the last part of my question, but not the first. I'm encrypting an input which is 32bytes: "1234567890abcdef1234567890abcdef", since the first 16 bytes are the same as the last 16 bytes, and since 16 bytes is the input block size, I would expect in the output the same cipher block twice. Am I missing something? – emitrax Apr 27 '21 at 14:05
  • I found my problem. I was not seeing the repeat block because I was running `hexdump` without the `-v` options which forces it to print everything. Now everything is clear and as I expect it. Thanks a lot. In both cases I see an additional block, I would assume that's related to padding. – emitrax Apr 27 '21 at 14:19
  • 1
    OK, thanks for clarifying that part of your question, and glad you figured out the answer to it. openssl will add padding, unless you tell it not to using the `-nopad` option (which of course is only valid if the input length is a multiple of 16 bytes). – mti2935 Apr 27 '21 at 14:25
3

In addition to why the first 8 bytes are the same, a bit more about why the outputs (ciphertexts) differ:

  1. You're using different algorithms. Even if the keys were the same, different algorithms produce different ciphertext from a given key+message input. This is true regardless of the mode of operation.
  2. As mentioned in the other answer, the keys are in fact different between runs, because you generated them from a password and the password-based key derivation function requires a salt. This salt is randomly generated for each message and stored (in plain text) with the output. Thus, the same password does not produce the same key.

You also ask why it prompts for a password. It is, indeed, used to generate the key. You aren't supplying a key - just a cipher, mode, and message - so it needs to come up with one from somewhere. Passwords aren't great sources of keys - very few humans can generate even 128 bits of memorable entropy on demand - but they are the most likely explanation for what the software is supposed to use when you say "encrypt this" but don't provide an encryption key.

CBHacking
  • 42,359
  • 3
  • 76
  • 107
  • Thanks for answering. I made the mistake of using the wrong input in the second example. I was not expecting the cipher text to be the same, I was expecting a repeating block in the cipher text, which I was not seeing because I was running `hexdump` without `-v`. Now everything is clear. Thanks a lot. – emitrax Apr 27 '21 at 14:21