douyiken0968 2018-06-14 13:34
浏览 55
已采纳

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

I am testing AES CTR in Go. I wrote the logic to encrypt / decrypt. Of course I searched for test vectors in order to verify that my encryption / decryption logic works. The first vector passes but the rest don't pass. I would appreciate if someone could checkout this code snipped and give me a hint why it's failing.

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("------")


    }

}

I found the test vectors 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

I am pretty sure that I did everything correct - but it's failing.

Thanks

  • 写回答

1条回答 默认 最新

  • dph58509 2018-06-14 14:20
    关注

    The "Input Block" for each test case is your IV, as you can see only the first matches the IV you've provided.

    Adding that passes all 4 tests: 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("------")
    }
    

    Alternatively, the reason for the changing "Input Block" is that these examples are meant to be chained together in the same stream, and those represent the state of the block after each example. You can see the CTR mode incrementing the last byte of the IV. Reusing the stream in this way will also pass all tests: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("------")
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮