Reputation: 391
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.
Upvotes: 5
Views: 208