我编写了以下代码来解密文件:
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的输出相同。