web-dev-qa-db-ja.com

Amazon KMSを使用した値の暗号化、DynamoDBとLambda(NodeJS)を使用した保存/取得

DynamoDBにデータを書き込むLambda(NodeJS)関数があります。そのデータの一部は暗号化する必要があります。 KMS暗号化と保存を使用して暗号化しています。別のLambda関数を使用してDynamoから取得し、復号化しようとすると、エラーが発生します。暗号化してから復号化する場合、それは可能ですが、暗号化された値をDBから読み取っている場合は復号化されません。私の暗号化/保存コードは以下の通りです:

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

暗号化された値を暗号化および復号化できますが、値を格納して取得し、復号化しようとすると失敗します。どんな助けでも大歓迎です。

18
scoDubblT

わかりました-私はこれを機能させており、誰かが同じことで苦労している可能性がある場合に備えて、ここに投稿したいと思いました。 DynamoDBにデータを入れるときは、次のようなものを使用します。

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

取得したときに文字列が返されず、オブジェクトが返されました。そのため、今取得したpersonという行がある場合、次のような値を取得する必要があります。

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

したがって、私が抱えていた問題は、person.First_Name.Sの値ではなく、オブジェクトperson.First_Nameを復号化メソッドに渡そうとしていたことです。

13
scoDubblT