無論IV如何,文本都被部分解密
我正在嘗試找出最適合使用的 AES 密碼。我正在使用OpenSSL ruby gem。
在測試各種選項時,我注意到大多數密碼都會導致部分甚至完全解密,而不管 IV 值如何。
我只是想知道這是否是我應該關注的事情,或者即使它是 gem 維護者應該注意的錯誤。
例如:CBC、CFB8、CFB1、CFB、CBC-HMAC-SHA256 和 CBC-HMAC-SHA1,只有前 16 個字節保持加密狀態。
例如:ECB 允許完全解密而不考慮 IV
這是我用於測試的 ruby 程式碼。
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 << 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 << 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 => e puts e.message end end
對於那些沒有 ruby 的人,這是上面程式碼的輸出:
== 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 == /& 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!��<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.
您實際上不是在談論“密碼”,而是在談論“操作模式”。
ECB 模式不使用 IV,因此在使用該模式時忽略其值。這是我們為什麼要使用操作模式的一個很好的例子。(ECB 是最快的操作模式,但它是最不安全的模式)這是使用 ECB 加密的 .bmp 圖像。(然後轉換為 .jpeg)
如您所見,您可以輕鬆推斷出原件上的內容。使用不同的操作模式(CBC)通常要困難得多。
現在圖像與雜訊無法區分,但仍有一些資訊可能洩漏。如果有人對同一圖像加密兩次,則兩種情況下的密文將相同。
這就是隨機 IV 的原因。即使圖像相同,不同的IV也會導緻密文完全不同。例如,這在加密密碼時很有用。兩個相同的密碼不應儲存為兩個相同的密文。
總之,IV不是為了防止密文的解密而製作的。這就是鑰匙的工作。當對手只能看到原始密文時,隨機 IV 用於防止“元數據”洩漏。
在大多數操作模式(如 CBC)中,“目前”塊通過以某種方式(通常通過 XOR)與先前的塊密文連接來掩蓋。
這使得沒有前驅的第一個塊沒有混淆。這就是IV發揮作用的地方。我們在密文中添加了一個虛假的“前一個塊”。(IV 通常被添加到密文之前,並且對手可以立即看到)在解密時,我們實際上僅將 IV 用於第一個塊。要破譯任何其他塊,您只需要密鑰和先前的密文(對手也可以看到)
當沒有提供 IV 時,第一個塊被解密為 $ Plaintext \oplus IV $ ,並且由於該塊通常是可預測的(如文件頭的第一個字元),因此通常可以很容易地猜測 IV。