I have a Lambda(NodeJS) function that writes data to DynamoDB. Some of that data needs to be encrypted. I'm encrypting using KMS encrypt and storing. When I retrieve from Dynamo using a different Lambda function and try to decrypt, I get an error. If I encrypt and then turn around a decrypt, I'm able to do that, but if I'm reading the encrypted value from the DB, it won't decrypt. My encrypt/store code is below:
console.log('Loading event');
var AWS = require('aws-sdk');
var keyId = "arn:aws:kms:us-east-1:5423542542:key/xxxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxxx";
var tableName = "person";
var dynamoDBConfiguration = {
"region": "us-west-2"
};
AWS.config.update(dynamoDBConfiguration);
var dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var kms = new AWS.KMS({region: 'us-east-1'});
var newId = "1234-56789-101112-13141516";
var item = {};
exports.handler = function (event, context) {
console.log('ssn');
//encrypt it
var ssnParams = {
KeyId: keyId,
Plaintext: "123-45-6789"
};
kms.encrypt(ssnParams, function (err, data) {
if (err) {
console.log(err, err.stack);
}
else {
console.log(' ssn encrypted');
var enc_ssn = data.CiphertextBlob;
item["SSN"] = {"Value": {"B": enc_ssn}};
item["First_Name"] = {"Value": {"S": "Joe"}};
item["Last_Name"] = {"Value": {"S": "Blow"}};
dynamodb.updateItem({
"TableName": tableName,
"AttributeUpdates": item,
"ReturnValues": "ALL_NEW",
"Key": {
"id": {"S": newId}
}
}, function (err, data) {
if (err) {
context.done(err);
}
else {
console.log('great success: %j', data);
context.succeed("Person Successfully Inserted");
}
});
}
});
};
My retrieval/decrypt code is as follows:
console.log('Loading event');
var AWS = require('aws-sdk');
var dynamoDBConfiguration = {
"region": "us-west-2"
};
AWS.config.update(dynamoDBConfiguration);
var dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var keyId = "arn:aws:kms:us-east-1:5423542542:key/xxxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxxx";
var tableName = "person";
var kms = new AWS.KMS({region: 'us-east-1'});
exports.handler = function (event, context) {
console.log(JSON.stringify(event, null, ' '));
var params = {};
var id = event.id;
console.log(id);
if (id && id !== '') {
params = {
"TableName": tableName,
KeyConditionExpression: "id = :id",
ExpressionAttributeValues: {
':id': {'S': id}
}
};
dynamodb.query(params, function (err, data) {
if (err) {
context.done(err);
}
else {
var person = data.Items[0];
console.log('query success');
console.log(person);
if (person.SSN) {
console.log('have ssn');
var b_ssn = person.SSN;
console.log(b_ssn);
person.SSNtext = "";
var encryptedParams = {
CiphertextBlob: Buffer(b_ssn, 'base64'),
};
kms.decrypt(encryptedParams, function (err, decrypteddata) {
if (err) {
console.log(err, err.stack);
//context.done(err);
}
else {
person.SSNtext = decrypteddata.Plaintext.toString();
console.log(decrypteddata.Plaintext.toString());
context.succeed(person);
}
});
}
}
});
}
else {
params = {
"TableName": tableName
};
dynamodb.scan(params, function (err, data) {
if (err) {
context.done(err);
}
else {
console.log('scan success');
context.succeed(data);
}
});
}
};
When I run this code, I get the following error:
START RequestId: 639590ac-cb95-11e5-91e4-d706c725f529 Version: $LATEST
2016-02-04T23:16:58.713Z 639590ac-cb95-11e5-91e4-d706c725f529 Loading event
2016-02-04T23:17:00.215Z 639590ac-cb95-11e5-91e4-d706c725f529 {
"id": "1234-56789-101112-13141516"
}
2016-02-04T23:17:00.215Z 639590ac-cb95-11e5-91e4-d706c725f529 1234-56789-101112-13141516
2016-02-04T23:17:00.954Z 639590ac-cb95-11e5-91e4-d706c725f529 query success
2016-02-04T23:17:00.954Z 639590ac-cb95-11e5-91e4-d706c725f529 { Last_Name: { S: 'Blow' },
id: { S: '1234-56789-101112-13141516' },
First_Name: { S: 'Joe' },
SSN: { B: <Buffer 0a 20 ec 00 75 21 f2 61 7d ba 2e 38 7e c6 fd 24 6d 32 b4 c2 b3 29 47 9e 9b 97 f2 a8 46 f2 d0 38 da 37 12 92 01 01 01 02 00 78 ec 00 75 21 f2 61 7d ba 2e ...> } }
2016-02-04T23:17:00.956Z 639590ac-cb95-11e5-91e4-d706c725f529 have ssn
2016-02-04T23:17:00.956Z 639590ac-cb95-11e5-91e4-d706c725f529 { B: <Buffer 0a 20 ec 00 75 21 f2 61 7d ba 2e 38 7e c6 fd 24 6d 32 b4 c2 b3 29 47 9e 9b 97 f2 a8 46 f2 d0 38 da 37 12 92 01 01 01 02 00 78 ec 00 75 21 f2 61 7d ba 2e ...> }
2016-02-04T23:17:01.573Z 639590ac-cb95-11e5-91e4-d706c725f529 { [InvalidCiphertextException: null]
message: null,
code: 'InvalidCiphertextException',
time: Thu Feb 04 2016 23:17:01 GMT+0000 (UTC),
I can encrypt and decrypt the encrypted value, but when I store the value, retrieve it and try to decrypt it, it fails. Any help would be greatly appreciated.
Binary
data type to store the encrypted data? According to the docs, you also need to encode the value in Base64 format. – Boris Serebrov