Как расшифровать безопасное строковое значение параметра ssm, возвращаемое ресурсом данных terraform

У меня есть код ниже terraofrm для получения параметра из магазина

data "aws_ssm_parameter" "foo" {
 name = "password"
with_decryption = false
}

module "lambda_env_vars" {
New_password = data.aws_ssm_parameter.foo.value
}

plan output:-
New_password = Q#iuws##)9ssdhs(some encryptrd value)

Как я могу расшифровать это в простой текст в лямбда-функции?

образец кода, который я пробовал.

import boto3
import os

from base64 import b64decode

def lambda_handler(event, context):
    encrypted = os.environ['New_password']
    decrypted = boto3.client('kms').decrypt(CiphertextBlob=b64decode(encrypted))['Plaintext']

    print("Decrypted value:", decrypted)

person SNR    schedule 01.09.2020    source источник
comment
почему бы вам просто не использовать boto3 для получения дешифрованного параметра вместо разделения этой логики на две части? Какую ошибку вы получаете сейчас?   -  person luk2302    schedule 01.09.2020
comment
Вы зашифровали параметр ssm ключом по умолчанию? Если да: вы меняли ключевую политику этого ключа? Разрешено ли вашей лямбде расшифровать что-нибудь?   -  person luk2302    schedule 01.09.2020
comment
В чем проблема? Есть сообщения об ошибках?   -  person Marcin    schedule 01.09.2020
comment
У меня нет знаний о Python, я прошу образец кода. Я просто однажды попробовал этот пример от Google и получил ошибку invalidciphertexception.   -  person SNR    schedule 01.09.2020


Ответы (2)


После некоторого исследования я обнаружил, что AWS Encryption SDK криптографически связывает контекст шифрования с зашифрованными данными reference, поэтому мы должны использовать то же самое для дешифрования. EncryptionContext решил проблему за меня.

Примечание. Это код узла js.

const aws = require('aws-sdk')
const kms = new aws.KMS()
exports.handler = async (event, context, callback) => {
  var password_json = JSON.parse(process.env.New_password)
  let params = {
    CiphertextBlob: Buffer.from(password_json['value'], 'base64'),
     EncryptionContext: {
        'PARAMETER_ARN': password_json['arn']
    }
  }

  let secret = null
    const decrypted = await kms.decrypt(params).promise()

          secret = decrypted.Plaintext.toString('utf-8')
    
  return secret;
}

Изменение Terraform

module "lambda_env_vars" {
New_password = jsonencode(data.aws_ssm_parameter.foo)
}

Переменные ENV в лямбда-консоли выглядят так

New_password {"arn":"arn:aws:ssm:xxxxx:41xxxxx:parameter/password","id":"password","name":"password","type":"SecureString","value":"xxxxxxxx","version":2,"with_decryption":false}

Таким образом (jsonencode) мы также можем избежать жесткого кодирования параметра ARN внутри кода.

person SNR    schedule 01.09.2020
comment
Почему вы вообще передаете зашифрованный секрет в функцию Lambda, а не просто получаете его из хранилища параметров SSM, расшифрованного в функции Lambda? - person ydaetskcoR; 01.09.2020
comment
Вы не должны задавать вопрос в своем ответе. Но ответ будет такой: так же, как вы получаете зашифрованный пароль, передавая arn как переменную среды. Но все же остается вопрос: зачем вы в первую очередь передаете зашифрованный пароль, передаете имя пароля и просто вызываете get_parameter на ssm вместо decrypt на kms. - person luk2302; 01.09.2020
comment
Из документов, которые вы сами связали: Вы можете расшифровать зашифрованное значение параметра защищенной строки, вызвав операцию AWS KMS Decrypt с правильным контекстом шифрования и зашифрованным значением параметра, которое возвращает операция System Manager GetParameter. Однако мы рекомендуем вам расшифровать значения параметров хранилища параметров с помощью операции GetParameter с параметром WithDecryption. - person luk2302; 01.09.2020
comment
Потому что в нашем случае количество вызовов API для дешифрования из SSM огромно, что дороже, чем кмс. так же экономичное решение с использованием Kms вместо SSM дешифрования. - person SNR; 01.09.2020
comment
Затем вы должны просто кешировать получение параметра в лямбда-выражении, кешировать на неопределенный срок, так как он никогда не изменится. Нет смысла расшифровывать / получать параметр для каждого вызова лямбда, а только один раз, когда создается среда выполнения лямбда. - person luk2302; 02.09.2020

Ниже приведен код Python с жестко заданным параметром ARN.

import base64
import boto3
import os
def decrypt(session, secret):
    client = session.client('kms')
    plaintext = client.decrypt(
        CiphertextBlob=bytes(base64.b64decode(secret)),
        EncryptionContext={
        'PARAMETER_ARN': 'arn:aws:ssm:us-east-1:xxxxx:parameter/password'
    }
    )
    return plaintext["Plaintext"]

session = boto3.session.Session()
encrypted = os.environ['New_password']

print decrypt(session, encrypted)
person SNR    schedule 12.09.2020