Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of Initialization Vector in openssl_encrypt

I had a look at this question, and wanted to do it for myself. When I ran this code (taken straight from this answer):

$textToEncrypt = "My super secret information."; $encryptionMethod = "AES-256-CBC";  // AES is used by the U.S. gov't to encrypt top secret documents. $secretHash = "25c6c7ff35b9979b151f2136cd13b0ff";  //To encrypt $encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash, '1234567812345678');  //To Decrypt $decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash);  //Result echo "Encrypted: $encryptedMessage <br>Decrypted: $decryptedMessage"; 

However I get the warning

openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended 

So I went and had a look at the docs, but there 'is no documentation'. I found this comment, but still no mention of what the Initialization Vector should be and how I should use it. Can anyone enlighten me?

I know I could have done some more Googleing, but Stackoverflow comes up first in so many search results I thought this question might be useful to anyone else who was having this problem.

like image 308
Alfo Avatar asked Aug 06 '12 00:08

Alfo


People also ask

Why is initialization vector needed?

An initialization vector is used to avoid repetition during the data encryption process, making it impossible for hackers who use dictionary attack to decrypt the exchanged encrypted message by discovering a pattern.

Do you need initialization vector to decrypt?

Yes, you must provide the same IV for encryption and decryption.

What is IV in Openssl_encrypt?

Warning: openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended in file phpseclib/Crypt/Base.php, line #1311. Running the same code on a redhat 7 system with openssl 1.0.

What is initialization vector in Java?

3. Initialization Vector (IV) We use an IV in a cryptographic algorithm as a starting state, adding this to a cipher to hide patterns in the encrypted data. This helps avoid the need to re-issue a new key after each invocation.


1 Answers

An IV is generally a random number that guarantees the encrypted text is unique.

To explain why it's needed, let's pretend we have a database of people's names encrypted with the key 'secret' and no IV.

1 John dsfa9p8y098hasdf 2 Paul po43pokdfgpo3k4y 3 John dsfa9p8y098hasdf 

If John 1 knows his cipher text (dsfa9p8y098hasdf) and has access to the other cipher texts, he can easily find other people named John.

Now in actuality, an encryption mode that requires an IV will always use one. If you don't specify an IV, it's automatically set to a bunch of null bytes. Imagine the first example but with a constant IV (00000000).

1 John dsfa9p8y098hasdf 00000000 2 Paul po43pokdfgpo3k4y 00000000 3 John dsfa9p8y098hasdf 00000000 

To prevent repeated cipher texts, we can encrypt the names using the same 'secret' key and random IV's:

1 John sdf875n90mh28458 45gh3546 2 Paul fg9087n5b60987nf 56897ngq 3 John gjhn0m89456vnler 8907345f 

As you can see, the two 'John' cipher texts are now different. Each IV is unique and has influenced the encryption process making the end result unique as well. John 1 now has no idea what user 3's name is.

Decryption requires the use of the same IV the text was encrypted with of course, which is why it must be stored in the database. The IV is of no use without the key so transmitting or storing it with the encrypted text is of no concern.

This is an overly simplistic example, but the truth is, not using IV's has serious security ramifications.


Now your code appears to be setting the IV (1234567812345678) but not using it on decryption. That's certain to fail.

You also may want to utilize some of PHP's IV generation functions. I think this should work for you:

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash, 0, $iv); $decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash, 0, $iv); 

For storage/transmission, you can simply concatenate the IV and cipher text like so:

$data = $iv.$encryptedMessage; 

Then on retrieval, pull the IV out for decryption:

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); $iv = substr($data, 0, $iv_size); $decryptedMessage = openssl_decrypt(substr($data, $iv_size), $encryptionMethod, $secretHash, 0, $iv); 

For more info, check out PHP's Mcrypt library. It's quite full featured and has tons of examples, many of which can help you out with openssh encryption implementations. http://php.net/manual/en/function.mcrypt-encrypt.php

like image 174
Joel Mellon Avatar answered Oct 24 '22 12:10

Joel Mellon