Text partially decrypted regardless of IV I'm trying to work out which AES cipher is best to use.  I'm working with the OpenSSL ruby gem.

While testing the various options I noticed that most of the ciphers result in partial or even full decryption regardless of the IV value.

I'm just wondering if this is something I should be concerned about, or even if it is a bug that the gem maintainers should be aware of.

Eg: CBC, CFB8, CFB1, CFB, CBC-HMAC-SHA256, and CBC-HMAC-SHA1, only the first 16 bytes remain encrypted.

Eg: ECB allows full decryption regardless of IV

This is the ruby code I've used for testing.

ciphers = [
    'AES-256-CBC', 'AES-256-CTR', 'AES-256-XTS',
    'AES-256-OFB', 'AES-256-OCB', 'AES-256-ECB',
    'AES-256-CFB8', 'AES-256-CFB1', 'AES-256-CFB',
    'AES-256-CBC-HMAC-SHA256', 'AES-256-CBC-HMAC-SHA1',
  ]

def encrypt(plain_text, pwd, salt, cipher_name)
  cipher = OpenSSL::Cipher.new(cipher_name)
  cipher.encrypt
  cipher.random_iv # purposefully set to random
  cipher.key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, 20000, cipher.key_len, OpenSSL::Digest::SHA256.new)
  encrypted = cipher.update(plain_text)
  encrypted &lt;&lt; cipher.final
end

def decrypt(encrypted, pwd, salt, cipher_name)
  cipher = OpenSSL::Cipher.new(cipher_name)
  cipher.decrypt
  cipher.random_iv # purposefully set to random
  cipher.key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, 20000, cipher.key_len, OpenSSL::Digest::SHA256.new)
  decrypted = cipher.update(encrypted)
  decrypted &lt;&lt; cipher.final
end

ciphers.each do |cipher_name|
  pwd = 'some hopefully not to easily guessable password'
  salt = OpenSSL::Random.random_bytes(16)
  plain_text = "Spicy jalapeno tail ribeye dolore ut. Pork belly ut porchetta culpa aliquip brisket shank est. Pastrami ribeye porchetta cow qui."
  begin
    puts
    puts '== %s ==' % cipher_name
    encrypted = encrypt(plain_text, pwd, salt, cipher_name)
    puts decrypt(encrypted, pwd, salt, cipher_name)
  rescue =&gt; e
    puts e.message
  end
end


For those without ruby, this is the output of the above code:

== AES-256-CBC ==
��l�~��u@�=o� ail ribeye dolore ut. Pork belly ut porchetta culpa aliquip brisket shank est. Pastrami ribeye porchetta cow qui.

== AES-256-CTR ==
/&amp;  q]$���{�YhwH�X*�N���.p�E�̕;�� 3|t�L
                                          v�'�﬉�T�KCأ���y�X���ՎR`/��]d`L�WI�"�?P���Ǖ�B|E�u5������Zq����LϠ�4

== AES-256-XTS ==
^��:ok
@6�4^O�cNJ��'�  C/ ���V�(�)k5��)��S
                                  ^�3���4�r��A���q�=����p�^�d3;�    �.U˕|k�U/�ʝ��y��qd�/���7HΒ����l�e

== AES-256-OFB ==
iH�"�=�tL�eG��Z~o
��moӦQ!��&lt;z��vր2}�#6�
���%�oM��XI#y�t���($���"~

== AES-256-OCB ==


== AES-256-ECB ==
Spicy jalapeno tail ribeye dolore ut. Pork belly ut porchetta culpa aliquip brisket shank est. Pastrami ribeye porchetta cow qui.

== AES-256-CFB8 ==
�xYa���ShR�
          ail ribeye dolore ut. Pork belly ut porchetta culpa aliquip brisket shank est. Pastrami ribeye porchetta cow qui.

== AES-256-CFB1 ==
+��g~ᲆ$e�
        ��ail ribeye dolore ut. Pork belly ut porchetta culpa aliquip brisket shank est. Pastrami ribeye porchetta cow qui.

== AES-256-CFB ==
���=�?)�2�96`�2�ail ribeye dolore ut. Pork belly ut porchetta culpa aliquip brisket shank est. Pastrami ribeye porchetta cow qui.

== AES-256-CBC-HMAC-SHA256 ==
_?��?���p��}ail ribeye dolore ut. Pork belly ut porchetta culpa aliquip brisket shank est. Pastrami ribeye porchetta cow qui.

== AES-256-CBC-HMAC-SHA1 ==
[˲��H"`��.qv�ail ribeye dolore ut. Pork belly ut porchetta culpa aliquip brisket shank est. Pastrami ribeye porchetta cow qui.
You are actually not talking about "ciphers" but about "modes of operations".

ECB mode does not use the IV so its value is ignored when using that mode. It's a great example of reason why do we even use modes of operation. (ECB is the fastest mode of operation, but it's the least secure one) This is an .bmp image encrypted using ECB. (and then converted to .jpeg)



As you can see you can easily deduce what was on the original. Using a different mode of operation (CBC) it's usually much harder.



Now the image is indistinguishable from noise, but there is still some info that can leak. If someone encrypts the same image twice the ciphertext will be identical in both cases.

 

And this i the reason for random IV. Even if the image is identical, the different IV will cause the ciphertext to be completely different. This is useful for example when encrypting passwords. Two identical passwords should not be stored as two identical ciphertexts.

In conclusion the IV is not made for preventing decryption of the ciphertext. That's the job of the key. Random IV is used to prevent leaking of "metadata" when adversary can see only raw ciphertexts.

In most of the modes of operation (like CBC) the "current" block is obscured by connecting it somehow (usually by XOR) with previous blocks ciphertext.



This leaves the first block which has no predecessor with no obfuscation. This is where the IV comes into play. We add a fake "previous block" into the ciphertext. (IV is usually prepended to ciphertext and is immediately visible to adversary) When deciphering we actually use the IV only for that first block. To decipher any other block all you need is the key and previous ciphertext (which is also visible to the adversary) 



When no IV is provided then the first block is getting decrypted into $Plaintext \oplus IV$, and since this block is usually predictable (like first characters of file header) this usually allows pretty easily to guess the IV.