2015-05-19 42 views
2

当我尝试再次解密相同的字节片时,我遇到解密问题。的代码为澄清三重DES解密在再次解密时返回错误的前16个字节

实施例:

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("qwerty") 
    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个字节不在源字节片中。

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

回答

5

短版本:不重用解密器对象。

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

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

+0

弗雷德里克,非常感谢!我只是重写我的代码,为每个迭代创建新的解密器,现在它工作正常。 – Yury