三重DES解密在再次解密时返回错误的前16个字节

时间:2015-05-19 12:49:55

标签: encryption go tripledes

当我尝试再次解密相同的字节切片时,我遇到了解密问题。

澄清代码示例:

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

正如您所看到的,第一个解密效果很好并返回有效结果, 但所有其他尝试返回错误的结果。 结果的前16个字节不像源字节片中那样。

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

1 个答案:

答案 0 :(得分:6)

简短版本:不要重复使用decrypter对象。

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

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