donglou1866
donglou1866
2016-10-30 05:13

在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条回答

  • doubingguan3425 doubingguan3425 5年前

    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.

    点赞 评论 复制链接分享