三重DES解密returns再次解密时前16字节错误

Triple DES decryption returns wrong first 16 bytes of when decrypted again

我尝试再次解密同一个字节片时遇到解密问题。

说明代码示例:

package main

import (
    "fmt"
    "crypto/cipher"
    "crypto/des"
)

const (
    // tripleKey is TripleDES key string (3x8 bytes)
    tripleKey = "12345678asdfghjkzxcvbnmq"
)

var (
    encrypter cipher.BlockMode
    decrypter cipher.BlockMode
)

func init() {
    // tripleDESChiper is chiper block based on tripleKey used for encryption/decryption
    tripleDESChiper, err := des.NewTripleDESCipher([]byte(tripleKey))
    if err != nil {
        panic(err)
    }

    // iv is Initialization Vector used for encrypter/decrypter creation
    ciphertext := []byte("0123456789qwerty")
    iv := ciphertext[:des.BlockSize]

    // create encrypter and decrypter
    encrypter = cipher.NewCBCEncrypter(tripleDESChiper, iv)
    decrypter = cipher.NewCBCDecrypter(tripleDESChiper, iv)
}

func main() {
    message := "12345678qwertyuia12345678zxcvbnm,12345678poiuytr"
    data := []byte(message)
    hash := encrypt(data)

    decoded1 := decrypt(hash)
    decoded2 := decrypt(hash)
    decoded3 := decrypt(hash)
    decoded4 := decrypt(hash)


    fmt.Printf("encrypted data :             %x\n", data)
    fmt.Printf("1 try of decryption result : %x\n", decoded1)
    fmt.Printf("2 try of decryption result : %x\n", decoded2)
    fmt.Printf("3 try of decryption result : %x\n", decoded3)
    fmt.Printf("4 try of decryption result : %x\n", decoded4)
}

func encrypt(msg []byte) []byte {
    encrypted := make([]byte, len(msg))
    encrypter.CryptBlocks(encrypted, msg)

    return encrypted
}

func decrypt(hash []byte) []byte {
    decrypted := make([]byte, len(hash))
    decrypter.CryptBlocks(decrypted, hash)

    return decrypted
}

此代码也可用且可运行 在 the playground.

结果如下:

encrypted data :             313233343536373871776572747975696131323334353637387a786376626e6d2c3132333435363738706f6975797472
1 try of decryption result : 313233343536373871776572747975696131323334353637387a786376626e6d2c3132333435363738706f6975797472
2 try of decryption result : 5e66fa74456402c271776572747975696131323334353637387a786376626e6d2c3132333435363738706f6975797472
3 try of decryption result : 5e66fa74456402c271776572747975696131323334353637387a786376626e6d2c3132333435363738706f6975797472
4 try of decryption result : 5e66fa74456402c271776572747975696131323334353637387a786376626e6d2c3132333435363738706f6975797472

如您所见,第一个解密效果很好并且 returns 有效结果, 但所有其他尝试 returns 都是错误的结果。 结果的前 16 个字节与源字节切片中的不同。

有人可以描述我做错了什么吗?

简短版本:不要重复使用解密器对象。

更长的版本:您在 CBC 模式下使用密码:加密数据时,块 N 的明文与块 N-1(或第一个块上的 IV)的密文进行异或运算.在解密时,这是反向完成的。

这意味着当您尝试重用解密器对象时,您不会得到正确的结果,因为状态不正确 - 它正在解密块,就好像它们是您消息中的后续块一样。 CBC 的一个特点是不正确的 IV 只会影响第一个解密的块。