I am not able to decrypt my messages I receive from my S3 bucket. They are encrypted with a KMS key. I use Node and Typescript.
I have tried some stuff but arrent able to make it work. Looking in to this links: https://github.com/gilt/node-s3-encryption-client/issues/3 and https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SES.html
My code look like this now:
import * as AWS from 'aws-sdk';
import * as crypto from 'crypto';
const s3 = new AWS.S3({ apiVersion: '2006-03-01', region: 'eu-west-1' });
const kms = new AWS.KMS({ apiVersion: '2014-11-01', region: 'eu-west-1' });
export const handler = LambdaUtils.lambdaHandler( 'onebox-email-service-SendMailToL4PFunction', async (event) => {
const record = event.Records[0];
const request = {
Bucket: record.s3.bucket.name,
Key: record.s3.object.key
};
const data = await s3.getObject(request).promise();
const decryptData = await decryptSES(data);
return decryptData;
}
);
export const decryptSES = async (objectData) => {
const metadata = objectData.Metadata || {};
const kmsKeyBase64 = metadata['x-amz-key-v2'];
const iv = metadata['x-amz-iv'];
const tagLen = (metadata['x-amz-tag-len'] || 0) / 8;
let algo = metadata['x-amz-cek-alg'];
const encryptionContext = JSON.parse(metadata['x-amz-matdesc']);
switch (algo) {
case 'AES/GCM/NoPadding':
algo = 'aes-256-gcm';
break;
case 'AES/CBC/PKCS5Padding':
algo = 'aes-256-cbc';
break;
default:
log.error({Message: 'Unsupported algorithm: ' + algo});
return;
}
if (typeof (kmsKeyBase64) === 'undefined') {
log.error('Error');
}
const kmsKeyBuffer = new Buffer(kmsKeyBase64, 'base64');
const returnValue = await kms.decrypt({ CiphertextBlob: kmsKeyBuffer, EncryptionContext: encryptionContext }, (err, kmsData) => {
if (err) {
log.error({err});
return null;
} else {
const data = objectData.Body.slice(0, -tagLen);
const decipher = crypto.createDecipheriv( algo, kmsKeys.Plaintext[0], new Buffer(iv, 'base64'));
if (tagLen !== 0) {
const tag = objectData.Body.slice(-tagLen);
decipher.setAuthTag(tag);
}
let dec = decipher.update(data, 'binary', 'utf8');
dec += decipher.final('utf8');
return dec;
}
}).promise();
return returnValue;
};
I get error in my lambda that look like this:
2019-02-05T17:06:19.015Z d9593ef7-635b-47b2-b881-ede2a396f88e Error: Invalid key length at new Decipheriv (crypto.js:267:16) at Object.createDecipheriv (crypto.js:627:10) at Response.l.decrypt (/var/task/email-from-s3.js:592:232696) at Request. (/var/runtime/node_modules/aws-sdk/lib/request.js:364:18) at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:105:20) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:77:10) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14) at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10) at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12) at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10 at Request. (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9) at Request. (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12) at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:115:18) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:77:10) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14) at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
What I can see in my logs I get the encrypted message from my s3 bucket, but then it is not possible to decrypt it.
Can someone please help me with this? I use Node and Typescript.