在Go和OpenSSL中解密文件时的结果不同

时间:2016-10-30 05:13:29

标签: encryption go

我编写了以下代码来解密文件:

data, err := ioutil.ReadFile("file.encrypted")
if err != nil {
    log.Fatal(err)
}

block, err := aes.NewCipher(key)
if err != nil {
    log.Fatal(err)
}

mode := cipher.NewCBCDecrypter(block, iv)

mode.CryptBlocks(data, data)

err = ioutil.WriteFile("file.decrypted", data, 0644)
if err != nil {
    log.Fatal(err)
}

我还使用OpenSSL解密了该文件:

openssl aes-128-cbc -d -in file.encrypted -out file.decrypted -iv $IV -K $KEY

Go程序的输出文件比OpenSSL的输出文件大8个字节。

OpenSSL生成的文件中的hexdump尾:

ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
ff ff ff ff ff ff ff ff                           |........|

Go程序生成的文件中的hexdump尾:

ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
ff ff ff ff ff ff ff ff  08 08 08 08 08 08 08 08  |................|

为什么08 08 08 08 08 08 08 08附加到Go程序的文件输出?

修改

正如BJ Black解释的那样,我的Go程序输出中额外字节的原因是PKCS填充。

文件在CBC模式下使用AES加密,因此纯文本输入应为块大小的倍数,添加填充以满足此要求。 AES的块大小为16字节,因此填充字节总数将始终在1到16个字节之间。每个填充字节的值等于填充字节总数,在我的情况下为0x08

因此,要找出添加到文件中的填充量,只需读取解密文件的最后一个字节并将该数字转换为int:

paddingBytes := int(data[len(data)-1])

然后可以像这样修改WriteFile函数:

err = ioutil.WriteFile("file.decrypted", data[:len(data)-paddingBytes], 0644)

现在我的Go程序输出与OpenSSL的输出相同。

1 个答案:

答案 0 :(得分:3)

您所看到的是PKCS填充,OSSL正在为您删除,默认情况下Go不是。请参阅相关的Reddit帖子here

基本上,请按照示例进行操作,然后您就可以了。