go - AES CTR 失败测试向量(一个除外)

标签 go encryption aes

我正在 Go 中测试 AES CTR。我写了加密/解密的逻辑。当然,我搜索了测试向量以验证我的加密/解密逻辑是否有效。第一个矢量通过但其余的不通过。 如果有人可以结帐,我将不胜感激 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

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

谢谢

最佳答案

每个测试用例的“输入 block ”是您的 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("------")
}

或者,更改“输入 block ”的原因是这些示例将在同一流中链接在一起,并且它们代表每个示例之后 block 的状态。您可以看到 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("------")
}

关于go - AES CTR 失败测试向量(一个除外),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50858782/

相关文章:

mysql - 如何使用 MySQL aes_encrypt 和 aes_decrypt?

go - 如何在 Golang 中计算 256 位整数的 log16

java - Java 中使用 Bouncy CaSTLe 进行 AES 加密

mysql - 托管在客户端时的数据库安全

java - 在 Java 中对文件使用基于密码的加密

python - 将二进制数据加密为二进制数据并解密

go - 为什么 golang 堆配置文件中的 'Total MB' 小于顶部的 'RES'?

go - 在Go语句“typesubscriber struct {…}”中,type有什么作用?

go - 如何使用 Math/Big int Golang

java - java 中的 AES256 错误