加密和ByteString边界

时间:2012-09-10 12:59:59

标签: haskell encryption aes

我有以下测试应用程序:

import Codec.Crypto.AES
import qualified Data.ByteString.Char8 as B

key = B.pack "Thisismykey....."

iv = B.pack "0000000000000001"

main = do 
     let myenc = crypt' CTR key iv Encrypt (B.pack "1234567812345678") 
     print (B.unpack myenc)

打印出以下结果: “\ 250 \ DC4 \ DC4 \ 255 \ 223 \ 221C \ ETBx \ 239sF \ nuZu”

如果我将明文“1234567812345678”更改为“1234567812345688” 我得到“\ 250 \ DC4 \ DC4 \ 255 \ 223 \ 221C \ ETBx \ 239sF \ nuUu”

如果我将明文更改为“1134567812345678” 我得到输出“\ 250 \ ETB \ DC4 \ 255 \ 223 \ 221C \ ETBx \ 239sF \ nuZu”

我现在非常惊讶,因为输入和输出之间显然存在可预测的相关性,恕我直言不应该发生。如果我在明文的前面改变了一些东西,那么只有输出的前面受到影响等等。可能是某种方式与字节串的8或16字节边界有关,我该如何解决这个问题呢?在这里误导我的是什么?

独立于CTR模式,应该注意到AES可以使用4x4字节数组,问题是关于单个数组的加密。根据我的理解,AES应该执行四轮混合,并且单个字节(16个中的一个)的改变应该导致至少50%的比特不同。因此,在我看来,它可以不是16字节明文末尾的变化恰好改变了密文的结尾和前面的变化改变了前面等等。据我所知,IV只作为一个计数器发挥作用当涉及多个4x4阵列时。

1 个答案:

答案 0 :(得分:7)

它与haskell无关。

阅读http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Initialization_vector_.28IV.29

由于您使用相同的IV在CTR模式下对邮件进行两次加密,因此不安全。 阅读有关加密算法的信息,尽量避免编写自己的加密代码,因为它更容易出现安全漏洞。

CTR模式的要求是(key,IV)对应该是唯一的。 简单的解决方案是为您加密的每条新消息生成一个新的IV。

[CTR模式安全漏洞的解释] https://crypto.stackexchange.com/questions/2991/why-must-iv-key-pairs-not-be-reused-in-ctr-mode

在CTR模式下F(IV +计数器,键)XOR Plaintext = CIPHER ..所以如果nonce和key保持相同,那么纯文本的F是相同的..所以如果$ C_1 $是$ P_1 $的密码并且$ C_2 $是$ P_2 $的密码然后

xor($C_1$,$C_2$) = xor($P_1$,$P_2$) for same (key,IV) pair

支持代码:

import Codec.Crypto.AES
import qualified Data.ByteString.Char8 as B
import qualified Data.ByteString as BS
import Data.Bits (xor) 

key = B.pack "Thisismykey....."

iv = B.pack "1234567891012131"
p1 =  (B.pack "1234567812345678") 
p2 =  (B.pack "1234567812345688") 
x = crypt' CTR key iv Encrypt p1 
y = crypt' CTR key iv Encrypt p2 

main = do 
     print $ BS.zipWith xor x y  
     print $ BS.zipWith xor p1 p2

输出

[0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0]
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0]