D.K.
D.K.

Reputation: 39

Different results when encrypting with OpenSSL

I have a strange case when I try to do encryption with OpenSSL

Details:

Terminal commands to encrypt file:

So the only difference in commands is that one uses plain text password while another uses the same password but in HEX form. So in my opinion the result of encryption should be the same. But the Base64 output is actually different.

Maybe somebody know and can hint what could be the case here?

Another case that now I develop a small application that encrypts files on Blackberry phone and I would that it would be compatible with other encryption software like OpenSSL that are available on PC. So the Base64 output of my application is not the same as OpenSSL produces with the given password.

The sample code looks like this:

String testKey = "testtesttesttest"; (example)

byte[] aesKeyAsBytes = testKey.getBytes();

AESKey aesKey = new AESKey(aesKeyAsBytes);

AESEncryptorEngine engine = new AESEncryptorEngine(aesKey);

CBCEncryptorEngine cengine=new CBCEncryptorEngine(engine, new InitializationVector(_initVector));

PKCS5FormatterEngine fengine = new PKCS5FormatterEngine(cengine);

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

BlockEncryptor cryptoStream = new BlockEncryptor(fengine, outputStream);

cryptoStream.write(plainText, 0, numOfPlainTextBytes);

cryptoStream.close();

byte[] cipherText = outputStream.toByteArray();

outputStream.close();

return cipherText;

Upvotes: 2

Views: 2778

Answers (2)

dave_thompson_085
dave_thompson_085

Reputation: 38771

From man page for enc which should be present on any Unixy system (sometimes under a modified section like 1ssl) or current release on the web:

-k password

    the password to derive the key from. This is for compatibility with 
    previous versions of OpenSSL. Superseded by the -pass argument.

-kfile filename

    read the password to derive the key from the first line of 
    filename. This is for compatibility with previous versions of 
    OpenSSL. Superseded by the -pass argument.

-K key

    the actual key to use: this must be represented as a string 
    comprised only of hex digits. If only the key is specified, the IV ...

Do you see any difference between '(the) password the key is derived from' and 'the actual key'?

PS: since -K does not do key derivation, the arguments related to salt -nosalt -salt -S have no effect on it and are ignored.

Upvotes: 2

Luke Joshua Park
Luke Joshua Park

Reputation: 9795

I used the following inputs as test data for this scenario:

Key (Hex): 01010101010101010101010101010101
IV  (Hex): 02020202020202020202020202020202
Plaintext: Hello, World!

Using the above inputs with the following command in OpenSSL:

openssl aes-128-cbc -K 01010101010101010101010101010101 -iv 02020202020202020202020202020202 -e -a -in in.txt -out out-openssl.txt

Gave me a result of:

wT6aF/PXrGhxEwyX6mNfXA==

Using the C# System.Security.Cryptography namespace, which has a raw AES implementation that we can test against, I used the following code:

using (AesManaged aes = new AesManaged())
{
    aes.KeySize = 128;
    aes.Padding = PaddingMode.PKCS7;

    aes.Key = new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
    aes.IV = new byte[] { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };

    byte[] plaintext = Encoding.UTF8.GetBytes("Hello, World!");
    ICryptoTransform t = aes.CreateEncryptor();
    byte[] ciphertext = t.TransformFinalBlock(plaintext, 0, plaintext.Length);

    Console.WriteLine(Convert.ToBase64String(ciphertext));
}

To produce the exact same base64 result of:

wT6aF/PXrGhxEwyX6mNfXA==

This demonstrates that the OpenSSL command above is the correct one to use if you wish for the key to be used exactly as provided (e.g. the -K flag with the uppercase K).

As I mentioned in comments, OpenSSL does use a KDF when providing a password as plaintext, as detailed in this answer.

Upvotes: 4

Related Questions