Description
I've been having issues similar to #376 and #423 with decryption streams and S3 where the decryption fails with an error
Error: Unsupported state or unable to authenticate data
at Decipheriv.final (internal/crypto/cipher.js:174:29)
at DecipherStream._onAuthTag (/app/aws-perm-test/node_modules/@aws-crypto/decrypt-node/build/main/decipher_stream.js:72:39)
I'm using @aws-crypto/client-node: 2.0.0
and primarily NodeJS 14.15.4 but have experienced the issues on node 12 and 10 as well.
From what I can tell its not an issue with S3 specifically, but rather just with streams and larger files and maybe I/O latency. I've included some sample code using file streaming instead of S3 that will produce the error in certain circumstances. Its a bit of a contrived example but it should demonstrate the behavior without introducing S3.
const { createReadStream, createWriteStream} = require('fs');
const { promisify } = require('util');
const { finished } = require('stream');
const { KmsKeyringNode, buildClient} = require('@aws-crypto/client-node');
const finishedAsync = promisify(finished)
// Required values for test
const kmsKeyId = process.env.KMS_KEY;
const inputFile = process.env.INPUT_FILENAME;
const outputFile = process.env.OUTPUT_FILENAME;
const encryptKeyring = new KmsKeyringNode({
generatorKeyId: kmsKeyId,
});
const { encryptStream, decryptStream } = buildClient();
const encryptedFileName = 'file.encrypted';
(async function() {
const step1Stream = createReadStream(inputFile)
.pipe(encryptStream(encryptKeyring))
.pipe(createWriteStream(encryptedFileName));
await finishedAsync(step1Stream);
const step2Stream = createReadStream(encryptedFileName)
.pipe(decryptStream(new KmsKeyringNode({ discovery: true })))
.once('error', (err) => {
console.error(err);
})
.pipe(createWriteStream(outputFile))
await finishedAsync(step2Stream);
console.log(`Process complete`);
}())
On my machine, this code works with small files (under 1MB) consistently. Files around 10MB seem to work sometimes but not others and any file over 100MB always fails. And if you comment out the pipe with the encryptStream and decryptStream, the remaining code works for files of any size.
Any help would be appreciated. Thank you.