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

huangapple go评论95阅读模式
英文:

Different result when decrypting file in Go and OpenSSL

问题

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

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生成的文件的十六进制转储的尾部:

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程序生成的文件的十六进制转储的尾部:

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  |................|

为什么Go程序输出的文件末尾附加了08 08 08 08 08 08 08 08

编辑:

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

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

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

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

然后,可以修改WriteFile函数如下:

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

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

英文:

I have written the following code to decrypt a file:

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)
}

I have also decrypted the file using OpenSSL:

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

Output file from Go program is 8 bytes larger than output file from from OpenSSL.

Tail of hexdump from file generated by OpenSSL:

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

Tail of hexdump from file generated by Go program:

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  |................|

Why is 08 08 08 08 08 08 08 08 appended to file output from Go program?

EDIT:

As BJ Black explains, the reason for extra bytes in output from my Go program is PKCS padding.

The file is encrypted with AES in CBC mode and therefore the plain text input shall be a multiple of block size, padding is added to fulfill this requirement. AES has a block size of 16 bytes so the total number of padding bytes will always be between 1 and 16 bytes. Each padding byte has a value equal to the total number of padding bytes which in my case is 0x08.

So, to find out the amount of padding added to the file, one just have to read the last byte of decrypted file and convert that number to int:

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

The WriteFile function can then be modified like this:

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

Now output from my Go program is identical to the output from OpenSSL.

答案1

得分: 3

你所看到的是PKCS填充,OSSL会自动为你移除它,而Go默认情况下不会。请参考相关的Reddit帖子这里

基本上,按照示例操作就可以了。

英文:

What you're seeing is PKCS padding, which OSSL is removing for you and Go isn't by default. See the relevant Reddit post here.

Basically, follow the example and you're good to go.

huangapple
  • 本文由 发表于 2016年10月30日 13:13:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/40326209.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定