AES CTR失败的测试向量(除了一个)

时间:2018-06-14 13:34:30

标签: go encryption aes

我正在测试Go中的AES点击率。我写了加密/解密的逻辑。当然,我搜索了测试向量,以验证我的加密/解密逻辑是否有效。第一个矢量通过,但其余的没有通过。 如果有人可以查看this代码,我会很感激,并给我一个提示,说明它为什么会失败。

type testVector struct {
    plainText string
    cipherText string
}

func main() {

    // encryption key
    encryptionKey, err := hex.DecodeString("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4")
    if err != nil {
        panic(err)
    }

    // init vector
    iv, err := hex.DecodeString("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
    if err != nil {
        panic(err)
    }

    // aes ctr test vectors
    testVectors := []testVector{
        testVector{
            plainText: "6bc1bee22e409f96e93d7e117393172a",
            cipherText: "601ec313775789a5b7a7f504bbf3d228",
        },
        testVector{
            plainText: "ae2d8a571e03ac9c9eb76fac45af8e51",
            cipherText: "f443e3ca4d62b59aca84e990cacaf5c5",
        },
        testVector{
            plainText: "30c81c46a35ce411e5fbc1191a0a52ef",
            cipherText: "2b0930daa23de94ce87017ba2d84988d",
        },
        testVector{
            plainText: "f69f2445df4f9b17ad2b417be66c3710",
            cipherText: "dfc9c58db67aada613c2dd08457941a6",
        },
    }

    for _, v := range testVectors {

        block, err := aes.NewCipher(encryptionKey)
        if err != nil {
                panic(err)
        }

        plainText, err := hex.DecodeString(v.plainText)
        if err != nil {
                panic(err)
        }

        // create cipher text
        cipherText := make([]byte, 16)

        // encrypt
        stream := cipher.NewCTR(block, iv)
        stream.XORKeyStream(cipherText, plainText)

        fmt.Println("expected: "+v.cipherText)
        fmt.Println("calculated" + hex.EncodeToString(cipherText))
        fmt.Println("------")


    }

}

我找到了测试向量here

> F.5.5 CTR-AES256.
> Encrypt Key 603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4 
> 
> Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff 
> 
> Block #1 
> Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff 
> Output Block 0bdf7df1591716335e9a8b15c860c502 
> Plaintext 6bc1bee22e409f96e93d7e117393172a 
> Ciphertext 601ec313775789a5b7a7f504bbf3d228 
> 
> Block #2 
> Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff00 
> Output Block 5a6e699d536119065433863c8f657b94 
> Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 
> Ciphertext f443e3ca4d62b59aca84e990cacaf5c5 
> 
> Block #3 
> Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff01 
> Output Block 1bc12c9c01610d5d0d8bd6a3378eca62 
> Plaintext 30c81c46a35ce411e5fbc1191a0a52ef 
> Ciphertext 2b0930daa23de94ce87017ba2d84988d 
> 
> Block #4 
> Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff02 
> Output Block 2956e1c8693536b1bee99c73a31576b6 
> Plaintext f69f2445df4f9b17ad2b417be66c3710 
> Ciphertext dfc9c58db67aada613c2dd08457941a6

我很确定我做的一切都是正确的 - 但它失败了。

由于

1 个答案:

答案 0 :(得分:1)

每个测试用例的“输入块”是您的IV,因为您只能看到您提供的IV的第一个匹配项。

添加通过所有4个测试:https://play.golang.org/p/96H-Sf-gCxG

// aes ctr test vectors
testVectors := []testVector{
    testVector{
        iv:         "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
        plainText:  "6bc1bee22e409f96e93d7e117393172a",
        cipherText: "601ec313775789a5b7a7f504bbf3d228",
    },
    testVector{
        iv:         "f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
        plainText:  "ae2d8a571e03ac9c9eb76fac45af8e51",
        cipherText: "f443e3ca4d62b59aca84e990cacaf5c5",
    },
    testVector{
        iv:         "f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
        plainText:  "30c81c46a35ce411e5fbc1191a0a52ef",
        cipherText: "2b0930daa23de94ce87017ba2d84988d",
    },
    testVector{
        iv:         "f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
        plainText:  "f69f2445df4f9b17ad2b417be66c3710",
        cipherText: "dfc9c58db67aada613c2dd08457941a6",
    },
}

for _, v := range testVectors {

    block, err := aes.NewCipher(encryptionKey)
    if err != nil {
        panic(err)
    }

    plainText, err := hex.DecodeString(v.plainText)
    if err != nil {
        panic(err)
    }

    iv, err := hex.DecodeString(v.iv)
    if err != nil {
        panic(err)
    }

    // create cipher text
    cipherText := make([]byte, 16)

    // encrypt
    stream := cipher.NewCTR(block, iv)
    stream.XORKeyStream(cipherText, plainText)

    fmt.Println("expected:  " + v.cipherText)
    fmt.Println("calculated:" + hex.EncodeToString(cipherText))
    fmt.Println("------")
}

或者,更改“输入块”的原因是这些示例意味着在同一个流中链接在一起,并且那些示例表示每个示例之后的块的状态。您可以看到CTR模式递增IV的最后一个字节。以这种方式重用流也将通过所有测试:https://play.golang.org/p/Adqu8KPN7ED

stream := cipher.NewCTR(block, iv)

for _, v := range testVectors {
    plainText, err := hex.DecodeString(v.plainText)
    if err != nil {
        panic(err)
    }

    // create cipher text
    cipherText := make([]byte, 16)

    // encrypt
    stream.XORKeyStream(cipherText, plainText)

    fmt.Println("expected:  " + v.cipherText)
    fmt.Println("calculated:" + hex.EncodeToString(cipherText))
    fmt.Println("------")
}