Шифрование значений с использованием Amazon KMS, сохранение/извлечение с использованием DynamoDB с помощью Lambda (NodeJS)

У меня есть функция Lambda (NodeJS), которая записывает данные в DynamoDB. Некоторые из этих данных должны быть зашифрованы. Я шифрую шифрование и хранение KMS. Когда я извлекаю из Dynamo с помощью другой функции Lambda и пытаюсь расшифровать, я получаю сообщение об ошибке. Если я зашифрую, а затем развернусь расшифровать, я смогу это сделать, но если я прочитаю зашифрованное значение из БД, он не расшифрует. Мой код шифрования/хранения находится ниже:

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");
                }
            });
        }
    });
};

Мой код поиска/дешифрования выглядит следующим образом:

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);
            }
        });
    }
};

Когда я запускаю этот код, я получаю следующую ошибку:

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),

Я могу зашифровать и расшифровать зашифрованное значение, но когда я храню значение, извлекаю его и пытаюсь его расшифровать, он терпит неудачу. Любая помощь будет принята с благодарностью.

Ответы

Ответ 1

Хорошо. У меня это работает, и я хотел опубликовать его здесь, если кто-то еще может бороться с тем же. Когда вы помещаете данные в DynamoDB, вы используете что-то вроде этого:

item["First_Name"] = {"Value":{"S": "Joe"}};

когда я его получил, я не получил строку обратно, у меня есть объект. Поэтому, когда у меня есть строка, называемая человеком, которую я только что получил, я должен получить значение, подобное этому:

first_name = person.First_Name.S;
//results in first_name = "Joe";

Итак, проблема, с которой я столкнулась, заключается в том, что я пытался передать объект person.First_Name в метод дешифрования, а не значение person.First_Name.S