Proessamento
Lógica de negócio
e codigo fonte
Fornecimento de chaves para o cliente
Para a lógica do fornecimento de chaves de dados para os clientes, em keys.py
, é feita utilizado o método generate_data_key()
do cliente AWS KMS do AWS SDK para python boto3.
py
def read_handler(event, context):
kms = boto3.client("kms")
response = kms.generate_data_key(
KeyId=os.environ["KMS_MASTER_KEY_ID"],
KeySpec="AES_256"
)
return {
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
},
"body": json.dumps({
"cipher": base64.b64encode(response["CiphertextBlob"]).decode(),
"secret": base64.b64encode(response["Plaintext"]).decode(),
})
}
Acesso aleatório aos dados armazenados
O acesso aos dados, em data_key_access.py
, é relacionado com a leitura e escrita de valores no banco de dados, é feita utilizado o serviço Amazon DynamoDB.
py
def create_read_handler(event, context):
if not "key_id" in event["pathParameters"]:
return {
"statusCode": 400,
"headers": {
"Access-Control-Allow-Origin": "*",
},
}
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(os.environ["DYNAMODB_DATA_TABLE_NAME"])
key_id = event["pathParameters"]["key_id"]
method = event["httpMethod"]
response = None
response = table.get_item(Key={"key_id": key_id})
item_found = "Item" in response
if method == "GET":
if not item_found:
return {
"statusCode": 404,
"headers": {
"Access-Control-Allow-Origin": "*",
},
}
return {
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
},
"body": json.dumps({"data": response["Item"]["bin"]}),
}
body = json.loads(event["body"])
if method == "POST":
if item_found:
return {
"statusCode": 400,
"headers": {
"Access-Control-Allow-Origin": "*",
},
}
table.put_item(
Item={
"key_id": key_id,
"bin": body["data"],
}
)
return {
"statusCode": 201,
"headers": {
"Access-Control-Allow-Origin": "*",
},
}
Modificação dos dados armazenados
A modificação aos dados, em data_key_modify.py
, é relacionado com a atualização e remoção de valores no banco de dados, é feita utilizado o serviço Amazon DynamoDB e o cliente KMS.
É utilizado também uma modificação do código crypto.py
do usuário do GitHub @tcitry para fazer a encriptação e decriptação AES-256 ECB utilizando a biblioteca cryptography.
py
def update_delete_handler(event, context):
if not "key_id" in event["pathParameters"]:
return {
"statusCode": 400,
"headers": {
"Access-Control-Allow-Origin": "*",
},
}
kms = boto3.client("kms")
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(os.environ["DYNAMODB_DATA_TABLE_NAME"])
key_id = event["pathParameters"]["key_id"]
method = event["httpMethod"]
headers = event["headers"]
body = json.loads(event["body"])
response = None
response = table.get_item(Key={"key_id": key_id})
if "Item" not in response:
return {
"statusCode": 404,
"headers": {
"Access-Control-Allow-Origin": "*",
},
}
elif headers is None or "Authorization" not in headers:
return {
"statusCode": 403,
"headers": {
"Access-Control-Allow-Origin": "*",
},
}
data = response["Item"]["bin"]
try:
kms_response = kms.decrypt(
KeyId=os.environ["KMS_MASTER_KEY_ID"],
CiphertextBlob=force_bytes(headers["Authorization"]),
)
verify_data = AES_256_ECB(kms_response["Plaintext"]).verify(data)
if not verify_data:
raise Exception()
if method == "PUT" and not AES_256_ECB(kms_response["Plaintext"]).verify(
body["data"]
):
raise Exception()
except Exception:
return {
"statusCode": 403,
"headers": {
"Access-Control-Allow-Origin": "*",
},
}
if method == "PUT":
table.update_item(
Key={"key_id": key_id},
UpdateExpression="SET bin = :val1",
ExpressionAttributeValues={":val1": body["data"]},
)
elif method == "DELETE":
table.delete_item(Key={"key_id": key_id})
return {
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*",
},
}
- Na linha 20, é feita a consulta do índice na base de dados;
- Da linha 40 à 43 é feita a decriptação da chave sifrada, obtendo a chave secreta;
- Na linha 45 é feita a verificação da chave secreta com o valor armazenado;
- Na linha 49 é feita a verificação da autenticicade da requisição;
- Da linha 62 à 66 é feita a atualização do valor na base de dados;
- Na linha 68 é feita a aremoção do valor da base de dados.