首页 文章

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

提问于
浏览
5

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

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程序的文件输出?

EDIT:

正如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 回答

  • 3

    你是什么're seeing is PKCS padding, which OSSL is removing for you and Go isn' t默认 . 请参阅相关的Reddit帖子here .

    基本上,按照这个例子,你很高兴 .

相关问题