Skip to content

KMS Stream Decryption Error #507

Closed
@cbeall

Description

@cbeall

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions