douyiken0968
douyiken0968
2018-06-14 13:34

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

  • aes
  • encryption
已采纳

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 dph58509 3年前

    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("------")
    }
    
    点赞 评论 复制链接分享

为你推荐