Validar resultados de consulta salva - AWS CloudTrail

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Validar resultados de consulta salva

Para determinar se os resultados da consulta foram modificados, excluídos ou inalterados após a CloudTrail entrega dos resultados da consulta, você pode usar a validação de integridade dos resultados da CloudTrail consulta. Esse recurso é criado usando algoritmos padrão do setor: SHA-256 para hashing e SHA-256 com RSA para assinaturas digitais. Isso torna computacionalmente inviável modificar, excluir ou falsificar arquivos de resultados de CloudTrail consultas sem detecção. Você pode usar a linha de comando para validar os arquivos de resultados de consulta.

Por que usá-la?

Os arquivos de resultado de consulta validados são valiosíssimos para segurança e investigações forenses. Por exemplo, um arquivo de resultado de consulta validado permite que você afirme positivamente que o arquivo de resultados da consulta em si não foi alterado. O processo de validação da integridade do arquivo de resultados da CloudTrail consulta também permite que você saiba se um arquivo de resultado da consulta foi excluído ou alterado.

Valide os resultados da consulta salvos com o AWS CLI

É possível validar a integridade dos arquivos de resultado de consultas e do arquivo de assinatura com o comando aws cloudtrail verify-query-results.

Pré-requisitos

Para validar a integridade dos resultados de consulta com a linha de comando, é necessário satisfazer as seguintes condições:

  • Você deve ter conectividade on-line com AWS.

  • Você deve usar a AWS CLI versão 2.

  • Para validar arquivos de resultados de consulta e o arquivo de assinatura localmente, as seguintes condições se aplicam:

    • É necessário colocar os arquivos de resultados de consulta e o arquivo de assinatura no caminho de arquivo especificado. Especifique o caminho do arquivo como o valor do parâmetro --local-export-path.

    • Você não deve renomear os arquivos de resultados de consulta e o arquivo de assinatura.

  • Para validar os arquivos de resultados de consulta e o arquivo de assinatura no bucket do S3, as seguintes condições se aplicam:

    • Você não deve renomear os arquivos de resultados de consulta e o arquivo de assinatura.

    • É necessário ter acesso de leitura ao bucket do Amazon S3 que contém os arquivos de resultado de consultas e de assinatura.

    • O prefixo do S3 especificado deve conter os arquivos de resultados de consulta e o arquivo de assinatura. Especifique o prefixo do S3 como o valor do parâmetro --s3-prefix.

verify-query-results

O comando verify-query-results verifica o valor de hash de cada arquivo de resultado de consulta, comparando o valor com fileHashValue no arquivo de assinatura e, em seguida, validando o valor hashSignature no arquivo de assinatura.

Ao verificar os resultados da consulta, você pode usar as opções de linha de comando --s3-bucket e --s3-prefix para validar os arquivos de resultados de consulta e o arquivo de assinatura armazenados em um bucket do S3 ou pode usar a opção de linha de comando --local-export-path para realizar uma validação local dos arquivos de resultados de consulta e do arquivo de assinatura baixados.

nota

O comando verify-query-results é específico da região. Você deve especificar a opção --region global para validar os resultados da consulta para uma específica Região da AWS.

Veja a seguir as opções para o comando verify-query-results.

--s3-bucket <string>

Especifica o nome do bucket do S3 que armazena os arquivos de resultados de consulta e o arquivo de assinatura. Não é possível usar esse parâmetro com --local-export-path.

--s3-prefix <string>

Especifica o caminho do S3 da pasta do S3 que contém os arquivos de resultados de consulta e o arquivo de assinatura (por exemplo, s3/path/). Não é possível usar esse parâmetro com --local-export-path. Esse parâmetro não precisará ser fornecido se os arquivos estiverem localizados no diretório raiz do bucket do S3.

--local-export-path <string>

Especifica o diretório local que contém os arquivos de resultados de consulta e o arquivo de assinatura (por exemplo, /local/path/to/export/file/). Não é possível usar esse parâmetro com --s3-bucket ou --s3-prefix.

Exemplos

O exemplo a seguir valida os resultados da consulta usando as opções de linha de comando --s3-bucket e --s3-prefix para especificar o nome e o prefixo do bucket do S3 que contém os arquivos de resultados de consulta e o arquivo de assinatura.

aws cloudtrail verify-query-results --s3-bucket bucket_name --s3-prefix prefix --region region

O exemplo a seguir valida os resultados da consulta baixados usando a opção de linha de comando --local-export-path para especificar o caminho local para os arquivos de resultados de consulta e o arquivo de assinatura. Para obter mais informações sobre como baixar arquivos de resultados de consulta, verifique Baixe os resultados de sua consulta salva no CloudTrail Lake.

aws cloudtrail verify-query-results --local-export-path local_file_path --region region

Resultados da validação

A tabela a seguir descreve as possíveis mensagens de validação de arquivos de resultados de consulta e de assinatura.

Tipo de arquivo Mensagem de validação Descrição
Sign file Successfully validated sign and query result files A assinatura do arquivo de assinatura é válida. Os arquivos de resultados de consulta aos quais ele faz referência podem ser verificados.
Query result file

ValidationError: "File file_name has inconsistent hash value with hash value recorded in sign file, hash value in sign file is expected_hash, but get computed_hash

A validação falhou porque o valor de hash do arquivo de resultados de consulta não correspondia ao fileHashValue do arquivo de assinatura.
Sign file

ValidationError: Invalid signature in sign file

A validação do arquivo de assinatura falhou porque a assinatura não é válida.

CloudTrail estrutura de arquivo de assinatura

O arquivo de assinatura contém o nome de cada arquivo de resultado de consulta do S3 que foi entregue ao seu bucket do Amazon S3 quando você salvou os resultados de consulta, o valor de hash de cada arquivo de resultado de consulta e a assinatura digital do arquivo. A assinatura digital e os valores de hash são usados para validar a integridade dos arquivos de resultado de consulta e do próprio arquivo de assinatura.

Local do arquivo de assinatura

O arquivo de assinatura é entregue a um local de bucket do Amazon S3 que segue essa sintaxe.

s3://s3-bucket-name/optional-prefix/AWSLogs/aws-account-ID/CloudTrail-Lake/Query/year/month/date/query-ID/result_sign.json

Amostra de conteúdo do arquivo de assinatura

O exemplo de arquivo de sinal a seguir contém informações sobre os resultados da consulta CloudTrail Lake.

{ "version": "1.0", "region": "us-east-1", "files": [ { "fileHashValue" : "de85a48b8a363033c891abd723181243620a3af3b6505f0a44db77e147e9c188", "fileName" : "result_1.csv.gz" } ], "hashAlgorithm" : "SHA-256", "signatureAlgorithm" : "SHA256withRSA", "queryCompleteTime": "2022-05-10T22:06:30Z", "hashSignature" : "7664652aaf1d5a17a12ba50abe6aca77c0ec76264bdf7dce71ac6d1c7781117c2a412e5820bccf473b1361306dff648feae20083ad3a27c6118172a81635829bdc7f7b795ebfabeb5259423b2fb2daa7d1d02f55791efa403dac553171e7ce5f9307d13e92eeec505da41685b4102c71ec5f1089168dacde702c8d39fed2f25e9216be5c49769b9db51037cb70a84b5712e1dffb005a74580c7fdcbb89a16b9b7674e327de4f5414701a772773a4c98eb008cca34228e294169901c735221e34cc643ead34628aabf1ba2c32e0cdf28ef403e8fe3772499ac61e21b70802dfddded9bea0ddfc3a021bf2a0b209f312ccee5a43f2b06aa35cac34638f7611e5d7", "publicKeyFingerprint" : "67b9fa73676d86966b449dd677850753" }

Descrições dos campos do arquivo de assinatura

Veja a seguir as descrições de cada campo no arquivo de assinatura:

version

A versão do arquivo de assinatura.

region

A região da AWS conta usada para salvar os resultados da consulta.

files.fileHashValue

O valor de hash com codificação hexadecimal do conteúdo do arquivo de log não compactado.

files.fileName

O nome do arquivo de resultado de consulta.

hashAlgorithm

O algoritmo de hash usado para fazer hash do arquivo de resultado de consulta.

signatureAlgorithm

O algoritmo usado para assinar o arquivo.

queryCompleteTime

Indica quando os resultados da consulta foram CloudTrail entregues ao bucket do S3. Você pode usar esse valor para encontrar a chave pública.

hashSignature

A assinatura de hash do arquivo.

publicKeyFingerprint

A impressão digital com codificação hexadecimal da chave pública usada para assinar o arquivo.

Implementações personalizadas da validação da integridade do arquivo de resultados da CloudTrail consulta

Como CloudTrail usa algoritmos criptográficos e funções de hash padrão do setor e disponíveis abertamente, você pode criar suas próprias ferramentas para validar a integridade dos arquivos de resultados da CloudTrail consulta. Quando você salva os resultados da consulta em um bucket do Amazon S3, CloudTrail entrega um arquivo de sinal para o seu bucket do S3. Você pode implementar sua própria solução de validação para validar os arquivos de resultados da assinatura e da consulta. Para obter mais informações sobre o arquivo de assinatura, consulte CloudTrail estrutura de arquivo de assinatura.

Este tópico descreve como o arquivo de assinatura é assinado e detalha as etapas que você precisará seguir para implementar uma solução que valide o arquivo de assinatura e os arquivos de resultado de consulta aos quais o arquivo de assinatura faz referência.

Entendendo como CloudTrail os arquivos de assinatura são assinados

CloudTrail os arquivos de assinatura são assinados com assinaturas digitais RSA. Para cada arquivo de sinal, CloudTrail faça o seguinte:

  1. Cria uma lista de hash contendo o valor de hash para cada arquivo de resultado de consulta.

  2. Obtém uma chave privada exclusiva para a região.

  3. Transmite o hash SHA-256 da string e a chave privada ao algoritmo de assinatura RSA, que produz uma assinatura digital.

  4. Codifica o código de byte da assinatura em formato hexadecimal.

  5. Coloca a assinatura digital no arquivo de assinatura.

Conteúdo da string de assinatura de dados

A string de assinatura de dados consiste no valor de hash para cada arquivo de resultado de consulta separado por um espaço. O arquivo de assinatura lista o fileHashValue para cada arquivo de resultado de consulta.

Etapas da implementação da validação personalizada

Ao implementar uma solução personalizada de validação, você precisará validar o arquivo de assinatura e os arquivos de resultado de consulta aos quais ele faz referência.

Validar o arquivo de assinatura

Para validar um arquivo de assinatura, você precisa da assinatura dele, da chave pública cuja chave privada foi usada para assiná-lo e de uma string de assinatura de dados computada.

  1. Obtenha o arquivo de assinatura.

  2. Verifique se o arquivo de assinatura foi recuperado de seu local original.

  3. Obtenha a assinatura com codificação hexadecimal do arquivo de assinatura.

  4. Obtenha a impressão digital com codificação hexadecimal da chave pública cuja chave privada foi usada para assinar o arquivo de assinatura.

  5. Recupere a chave pública do intervalo de tempo correspondente a queryCompleteTime no arquivo de assinatura. Para o intervalo de tempo, escolha um StartTime anterior a queryCompleteTime e um EndTime posterior a queryCompleteTime.

  6. Entre as chaves públicas recuperadas, escolha aquela cuja impressão digital corresponda ao valor publicKeyFingerprint no arquivo de assinatura.

  7. Usando uma lista de hash contendo o valor de hash para cada arquivo de resultado de consulta separado por um espaço, recrie a string de assinatura de dados usada para verificar a assinatura do arquivo de assinatura. O arquivo de assinatura lista o fileHashValue para cada arquivo de resultado de consulta.

    Por exemplo, se a matriz files do seu arquivo de assinatura contiver os três arquivos de resultados de consulta a seguir, sua lista de hash será “aaa bbb ccc”.

    “files": [
 {
 "fileHashValue" : “aaa”,
 "fileName" : "result_1.csv.gz"
 }, {
 "fileHashValue" : “bbb”,
 "fileName" : "result_2.csv.gz"
 }, {
 "fileHashValue" : “ccc”,
 "fileName" : "result_3.csv.gz"
 } ],
  8. Para validar a assinatura, transmita o hash SHA-256 da string, a chave pública e a assinatura como parâmetros ao algoritmo de verificação de assinatura RSA. Se o resultado for verdadeiro, o arquivo de assinatura será válido.

Validar os arquivos de resultados de consulta

Se o arquivo de assinatura for válido, valide os arquivos de resultados de consulta aos quais o arquivo de assinatura faz referência. Para validar a integridade de um arquivo de resultado de consulta, calcule seu valor de hash SHA-256 em seu conteúdo compactado e compare os resultados com o fileHashValue do arquivo de resultado de consulta registrado no arquivo de assinatura. Se os hashes forem correspondentes, o arquivo de resultado de consulta será válido.

As seções a seguir descrevem o processo de validação em detalhes.

A. Obter o arquivo de assinatura

Os primeiros passos são obter o arquivo de assinatura e obter a impressão digital da chave pública.

  1. Obtenha o arquivo de assinatura do seu bucket do Amazon S3 para os resultados de consulta que deseja validar.

  2. Em seguida, obtenha o valor hashSignature do arquivo de assinatura.

  3. No arquivo de assinatura, obtenha a impressão digital da chave pública cuja chave privada foi usada para assinar o arquivo do campo publicKeyFingerprint.

B. Recuperar a chave pública para validar o arquivo de assinatura

Para obter a chave pública para validar o arquivo de assinatura, você pode usar a API AWS CLI ou a CloudTrail API. Em ambos os casos, você especifica um intervalo de tempo (ou seja, um horário de início e de término) para o arquivo de assinatura que você deseja validar. Use um intervalo de tempo correspondente a queryCompleteTime no arquivo de assinatura. Uma ou mais chaves públicas podem ser retornadas para o período que você especificar. As chaves retornadas podem ter períodos de validade que se sobrepõem.

nota

Como CloudTrail usa diferentes pares de chaves privadas/públicas por região, cada arquivo de sinal é assinado com uma chave privada exclusiva para sua região. Portanto, quando você valida um arquivo de assinatura de uma região específica, precisa recuperar a chave pública da mesma região.

Use o AWS CLI para recuperar chaves públicas

Para recuperar uma chave pública para um arquivo de sinal usando o AWS CLI, use o cloudtrail list-public-keys comando. O comando tem o formato a seguir:

aws cloudtrail list-public-keys [--start-time <start-time>] [--end-time <end-time>]

Os parâmetros de horário de início e de término são carimbos de data e hora UTC opcionais. Se eles não forem especificados, a hora atual será usada, e a chave ou as chaves públicas atualmente ativas serão retornadas.

Exemplo de resposta

A resposta será uma lista de objetos JSON que representam a chave ou as chaves retornadas:

Use a CloudTrail API para recuperar chaves públicas

Para recuperar uma chave pública para um arquivo de assinatura usando a CloudTrail API, transmita os valores de hora de início e hora de término para a ListPublicKeys API. A API ListPublicKeys retorna as chaves públicas cujas chaves privadas foram usadas para assinar o arquivo dentro do período especificado. Para cada chave pública, a API também retorna a impressão digital correspondente.

ListPublicKeys

Esta seção descreve os parâmetros de solicitação e os elementos de resposta da API ListPublicKeys.

nota

A codificação dos campos binários de ListPublicKeys está sujeita a alterações.

Parâmetros de solicitação

Nome Descrição
StartTime

Opcionalmente, especifica, em UTC, o início do intervalo de tempo para pesquisar a chave pública para o arquivo de assinatura. CloudTrail Se não StartTime for especificado, a hora atual será usada e a chave pública atual será retornada.

Tipo: DateTime

EndTime

Opcionalmente, especifica, em UTC, o final do intervalo de tempo para pesquisar chaves públicas para arquivos de assinatura. CloudTrail Se não EndTime for especificado, a hora atual será usada.

Tipo: DateTime

Elementos de resposta

PublicKeyList, um conjunto de PublicKey objetos que contém:

Name (Nome) Descrição
Value

O valor de chave pública codificado DER no formato PKCS #1.

Tipo: Blob

ValidityStartTime

O horário de início da validade da chave pública.

Tipo: DateTime

ValidityEndTime

O horário de término da validade da chave pública.

Tipo: DateTime

Fingerprint

A impressão digital da chave pública. A impressão digital pode ser usada para identificar a chave pública que você precisa usar para validar o arquivo de assinatura.

Tipo: string

C. Escolha a chave pública a ser usada para a validação

Entre as chaves públicas recuperadas por list-public-keys ou ListPublicKeys, escolha a chave pública cuja impressão digital corresponde à impressão digital gravada no campo publicKeyFingerprint do arquivo de assinatura. Essa é a chave pública que você usará para validar o arquivo de assinatura.

D. Recrie a string de assinatura de dados

Agora que você tem a assinatura do arquivo de assinatura e a chave pública associada, precisa calcular a string de assinatura de dados. Depois que você calcular a string de assinatura de dados, terá o necessário para verificar a assinatura.

A string de assinatura de dados consiste no valor de hash para cada arquivo de resultado de consulta separado por um espaço. Depois que você recriar essa string, poderá validar o arquivo de assinatura.

E. Validar o arquivo de assinatura

Transmita a string de assinatura de dados recriada, a assinatura digital e a chave pública ao algoritmo de verificação de assinatura RSA. Se o resultado for verdadeiro, a assinatura do arquivo de assinatura será verificada, e o arquivo de assinatura será válido.

F. Validar os arquivos de resultados de consulta

Depois que você validar o arquivo de assinatura, poderá validar os arquivos de resultado de consulta aos quais ele faz referência. O arquivo de assinatura contém os hashes SHA-256 dos arquivos de resultado de consulta. Se um dos arquivos de resultados da consulta for modificado após a CloudTrail entrega, os hashes SHA-256 serão alterados e a assinatura do arquivo de assinatura não corresponderá.

Siga o procedimento abaixo para validar os arquivos de resultados de consulta listados na matriz files do arquivo de assinatura.

  1. Recupere o hash original do arquivo no campo files.fileHashValue do arquivo de assinatura.

  2. Faça o hash do conteúdo compactado do arquivo de resultado de consulta com o algoritmo de hashing especificado em hashAlgorithm.

  3. Compare o valor de hash que você gerou para cada arquivo de resultado de consulta com o files.fileHashValue do arquivo de assinatura. Se os hashes forem correspondentes, os arquivos de resultado de consulta serão válidos.

Validação offline de arquivos de resultado de consulta e assinatura

Ao validar offline os arquivos de resultado de consulta e assinatura, você pode seguir os procedimentos descritos nas seções anteriores. No entanto, você deve levar em consideração as seguintes informações sobre chaves públicas.

Chaves públicas

Para fazer a validação offline, primeiramente é necessário obter online (p. ex., chamando ListPublicKeys) a chave pública de que você precisa para validar os arquivos de resultado de consulta em um determinado intervalo de tempo e, depois, armazená-la offline. Essa etapa precisará ser repetida sempre que você quiser validar arquivos adicionais fora do período inicial que especificou.

Exemplo de snippet de validação

O trecho de amostra a seguir fornece um código básico para validar arquivos de resultados de CloudTrail assinatura e consulta. O código esqueleto pode ser online ou offline, ou seja, você decide se o implementará com ou sem conectividade online na AWS. A implementação sugerida usa Java Cryptography Extension (JCE) e Bouncy Castle como um provedor de segurança.

O exemplo de snippet mostra:

  • Como criar a string de assinatura de dados usada para validar a assinatura do arquivo de assinatura.

  • Como verificar a assinatura do arquivo de assinatura.

  • Como calcular o valor de hash para o arquivo de resultado de consulta e compará-lo com o fileHashValue listado no arquivo de assinatura para verificar a autenticidade do arquivo de resultado de consulta.

import org.apache.commons.codec.binary.Hex; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.json.JSONArray; import org.json.JSONObject; import java.security.KeyFactory; import java.security.MessageDigest; import java.security.PublicKey; import java.security.Security; import java.security.Signature; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class SignFileValidationSampleCode { public void validateSignFile(String s3Bucket, String s3PrefixPath) throws Exception { MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); // Load the sign file from S3 (using Amazon S3 Client) or from your local copy JSONObject signFile = loadSignFileToMemory(s3Bucket, String.format("%s/%s", s3PrefixPath, "result_sign.json")); // Using the Bouncy Castle provider as a JCE security provider - http://www.bouncycastle.org/ Security.addProvider(new BouncyCastleProvider()); List<String> hashList = new ArrayList<>(); JSONArray jsonArray = signFile.getJSONArray("files"); for (int i = 0; i < jsonArray.length(); i++) { JSONObject file = jsonArray.getJSONObject(i); String fileS3ObjectKey = String.format("%s/%s", s3PrefixPath, file.getString("fileName")); // Load the export file from S3 (using Amazon S3 Client) or from your local copy byte[] exportFileContent = loadCompressedExportFileInMemory(s3Bucket, fileS3ObjectKey); messageDigest.update(exportFileContent); byte[] exportFileHash = messageDigest.digest(); messageDigest.reset(); byte[] expectedHash = Hex.decodeHex(file.getString("fileHashValue")); boolean signaturesMatch = Arrays.equals(expectedHash, exportFileHash); if (!signaturesMatch) { System.err.println(String.format("Export file: %s/%s hash doesn't match.\tExpected: %s Actual: %s", s3Bucket, fileS3ObjectKey, Hex.encodeHexString(expectedHash), Hex.encodeHexString(exportFileHash))); } else { System.out.println(String.format("Export file: %s/%s hash match", s3Bucket, fileS3ObjectKey)); } hashList.add(file.getString("fileHashValue")); } String hashListString = hashList.stream().collect(Collectors.joining(" ")); /* NOTE: To find the right public key to verify the signature, call CloudTrail ListPublicKey API to get a list of public keys, then match by the publicKeyFingerprint in the sign file. Also, the public key bytes returned from ListPublicKey API are DER encoded in PKCS#1 format: PublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, PublicKey BIT STRING } AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY DEFINED BY algorithm OPTIONAL } */ byte[] pkcs1PublicKeyBytes = getPublicKey(signFile.getString("queryCompleteTime"), signFile.getString("publicKeyFingerprint")); byte[] signatureContent = Hex.decodeHex(signFile.getString("hashSignature")); // Transform the PKCS#1 formatted public key to x.509 format. RSAPublicKey rsaPublicKey = RSAPublicKey.getInstance(pkcs1PublicKeyBytes); AlgorithmIdentifier rsaEncryption = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, null); SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo(rsaEncryption, rsaPublicKey); // Create the PublicKey object needed for the signature validation PublicKey publicKey = KeyFactory.getInstance("RSA", "BC") .generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded())); // Verify signature Signature signature = Signature.getInstance("SHA256withRSA", "BC"); signature.initVerify(publicKey); signature.update(hashListString.getBytes("UTF-8")); if (signature.verify(signatureContent)) { System.out.println("Sign file signature is valid."); } else { System.err.println("Sign file signature failed validation."); } System.out.println("Sign file validation completed."); } }