Exemplos de AWS Encryption SDK para C - SDK de criptografia da AWS

Se fornecermos uma tradução da versão em inglês do guia, a versão em inglês prevalecerá caso haja qualquer conflito entre as versões. A tradução é fornecida com o uso de tradução por máquina.

Exemplos de AWS Encryption SDK para C

Os exemplos a seguir mostram como usar o AWS Encryption SDK para C para criptografar e descriptografar dados.

Ao instalar e criar o AWS Encryption SDK para C, o código-fonte para estes e outros exemplos está incluído no subdiretório examples e é compilado e criado no diretório build. Você também pode localizá-los no subdiretório examples do repositório do aws-encryption-sdk-c no GitHub.

Criptografar e descriptografar strings

O exemplo a seguir mostra como usar o AWS Encryption SDK para C para criptografar e descriptografar uma string.

Este exemplo apresenta o token de autenticação do KMS, um tipo de token de autenticação que usa uma Chave mestra do cliente (CMK) do AWS Key Management Service (AWS KMS) para gerar e criptografar chaves de dados. O exemplo inclui algum código escrito em C++ porque o AWS Encryption SDK para C usa o AWS SDK para C++ para chamar o AWS KMS.

Para obter ajuda para criar uma CMK, consulte Criar chaves no AWS Key Management Service Developer Guide. Para ajudar a identificar CMKs em um Token de autenticação do AWS KMS, consulte Identificar CMKs em um token de autenticação do AWS KMS

Consulte o exemplo de código completo: string.cpp

Criptografar uma string

A primeira parte deste exemplo usa um Token de autenticação do AWS KMS com uma CMK para criptografar uma string de texto simples.

Etapa 1 Construa o keyring.

Crie um Token de autenticação do AWS KMS para criptografia. O token de autenticação neste exemplo é configurado com uma CMK, mas você pode configurar um Token de autenticação do AWS KMS com várias CMKs, inclusive CMKs em diferentes regiões e contas da AWS.

Para identificar uma CMK do AWS KMS em um token de autenticação de criptografia, especifique um ARN de chave ou um ARN de alias. Em um token de autenticação de descriptografia, é necessário usar um ARN de chave. Para obter mais detalhes, consulte Identificar CMKs em um token de autenticação do AWS KMS.

Identificar CMKs em um token de autenticação do AWS KMS

Ao criar um token de autenticação com várias CMKs, você especifica a CMK usada para gerar e criptografar a chave de dados de texto simples e uma matriz opcional de CMKs adicionais que criptografam a mesma chave de dados de texto simples. Nesse caso, especificamos apenas a CMK geradora.

Antes de executar esse código, substitua o ARN da chave de exemplo por um válido.

const char * key_arn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"; struct aws_cryptosdk_keyring *kms_keyring = Aws::Cryptosdk::KmsKeyring::Builder().Build(key_arn);
Etapa 2. Crie uma sessão.

Crie uma sessão usando o alocador, um enumerador de modo e o token de autenticação.

Cada sessão requer um modo: AWS_CRYPTOSDK_ENCRYPT para criptografar ou AWS_CRYPTOSDK_DECRYPT para descriptografar. Para alterar o modo de uma sessão existente, use o método aws_cryptosdk_session_reset.

Depois de criar um sessão com o token de autenticação, você poderá liberar sua referência ao token de autenticação usando o método fornecido pelo SDK. A sessão retém uma referência ao objeto token de autenticação durante sua vida útil. Referências ao token de autenticação e aos objetos de sessão são liberadas quando você destrói a sessão. Essa técnica de contagem de referência ajuda a evitar vazamentos de memória e a evitar que os objetos sejam liberados enquanto estão em uso.

struct aws_cryptosdk_session *session = aws_cryptosdk_session_new_from_keyring(alloc, AWS_CRYPTOSDK_ENCRYPT, kms_keyring); // When you add the keyring to the session, release the keyring object aws_cryptosdk_keyring_release(kms_keyring);
Etapa 3 Defina o tamanho dos dados de sequência.

Use o método aws_cryptosdk_session_set_message_size para informar ao SDK o tamanho exato da string em texto simples. Essa chamada de método não é necessária na descriptografia porque o SDK obtém o tamanho do texto cifrado da mensagem criptografada.

const char *plaintext_input = "Hello world!"; const size_t plaintext_len_input = strlen(plaintext_input); aws_cryptosdk_session_set_message_size(session, plaintext_len_input)
Etapa 4. Defina o contexto de encriptação.

Um contexto de criptografia são dados autenticados adicionais arbitrários e que não são secretos. Quando você fornece um contexto de criptografia na criptografia, o SDK de criptografia da AWS vincula de forma criptográfica o contexto ao texto cifrado, de forma que o mesmo contexto de criptografia seja necessário para descriptografar os dados. O uso de um contexto de criptografia é opcional, mas o recomendamos como uma melhor prática.

Primeiro, crie uma tabela de hash que inclua as strings de contexto de criptografia.

// Allocate a hash table for the encryption context. int set_up_enc_ctx(struct aws_allocator *alloc, struct aws_hash_table *my_enc_ctx) // Create encryption context strings AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_key1, "Example"); AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_value1, "String"); AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_key2, "Company"); AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_value2, "MyCryptoCorp"); // Put the key-value pairs in the hash table aws_hash_table_put(my_enc_ctx, enc_ctx_key1, (void *)enc_ctx_value1, &was_created) aws_hash_table_put(my_enc_ctx, enc_ctx_key2, (void *)enc_ctx_value2, &was_created)

Obtenha um ponteiro mutável para o contexto de criptografia na sessão. Depois, use a função aws_cryptosdk_enc_ctx_clone para copiar o contexto de criptografia na sessão. Mantemos a cópia em my_enc_ctx para que possamos validar o valor depois de descriptografar os dados.

O contexto de criptografia faz parte da sessão, não é um parâmetro transmitido para a função de processo da sessão. Isso garante que o mesmo contexto de criptografia seja usado para todos os segmentos de uma mensagem, mesmo se a função de processo de sessão for chamada várias vezes para criptografar a mensagem inteira.

struct aws_hash_table *session_enc_ctx = aws_cryptosdk_session_get_enc_ctx_ptr_mut(session); aws_cryptosdk_enc_ctx_clone(alloc, session_enc_ctx, my_enc_ctx)
Etapa 5. Encripte a cadeia.

Para criptografar a string em texto simples, use o método aws_cryptosdk_session_process com a sessão no modo de criptografia.

Na criptografia, os campos em texto simples são campos de entrada; os campos em texto cifrado são campos de saída. Concluído o processamento, o campo ciphertext_output conterá a mensagem criptografada, incluindo o texto cifrado real, as chaves de dados criptografadas e o contexto de criptografia. Você pode descriptografar essa mensagem criptografada usando o SDK de criptografia da AWS em qualquer linguagem de programação compatível.

// Gets the length of the plaintext that the session processed size_t plaintext_consumed_output; aws_cryptosdk_session_process(session, ciphertext_output, ciphertext_buf_sz_output, ciphertext_len_output, plaintext_input, plaintext_len_input, &plaintext_consumed_output)
Etapa 6. Limpe a sessão.

As etapas finais verificam se o processamento da sessão foi concluído e se todo o texto simples foi processado. Depois, elas destroem a sessão, inclusive as referências ao CMM e ao token de autenticação.

Se você preferir, em vez de destruir a sessão, reutilize-a com o mesmo token de autenticação e o CMM para descriptografar a string, ou para criptografar ou descriptografar outras mensagens. Para usar a sessão para descriptografia, use o método aws_cryptosdk_session_reset para alterar o modo para AWS_CRYPTOSDK_DECRYPT.

if (!aws_cryptosdk_session_is_done(session)) { aws_cryptosdk_session_destroy(session); return 8; } if (plaintext_consumed != plaintext_len) abort(); aws_cryptosdk_session_destroy(session);

Descriptografar uma string

A segunda parte deste exemplo descriptografa uma mensagem criptografada que contém o texto cifrado da string original.

Etapa 1 Construa o keyring.

Ao descriptografar dados no AWS KMS, você transmite a mensagem criptografada retornada pela API de criptografia. A API de descriptografia não precisa de uma CMK como entrada. Em vez disso, o AWS KMS usa a mesma CMK para descriptografar o texto cifrado usado para criptografá-lo. No entanto, o SDK de criptografia da AWS permite especificar um Token de autenticação do AWS KMS com CMKs ao criptografar e ao descriptografar.

Ao descriptografar, você pode configurar um token de autenticação com apenas as CMKs que você deseja usar para descriptografar a mensagem criptografada. Por exemplo, talvez você queira criar um token de autenticação com apenas a CMK usada por uma função específica em sua organização. O SDK de criptografia da AWS nunca usa uma CMK, a menos que ela apareça no token de autenticação de descriptografia. Se o SDK não puder descriptografar as chaves de dados criptografadas usando as CMKs no token de autenticação que você fornecer, seja porque nenhuma das CMKs no token de autenticação foi usada para criptografar nenhuma da chaves de dados ou porque o chamador não tem permissão para usar as CMKs no token de autenticação para descriptografar, ocorrerá uma falha na chamada de descriptografia.

Ao especificar uma CMK do AWS KMS para um token de autenticação de descriptografia, é necessário usar o ARN dessa chave. Os ARNs de alias são permitidos somente em tokens de autenticação de criptografia. Para ajudar a identificar CMKs em um Token de autenticação do AWS KMS, consulte Identificar CMKs em um token de autenticação do AWS KMS.

Neste exemplo, especificamos um token de autenticação configurado com a mesma CMK usada para criptografar a string. Antes de executar esse código, substitua o ARN da chave de exemplo por um válido.

const char * key_arn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab" struct aws_cryptosdk_keyring *kms_keyring = Aws::Cryptosdk::KmsKeyring::Builder().Build(key_arn);
Etapa 2. Crie uma sessão.

Crie uma sessão usando o alocador e o token de autenticação. Para configurar a sessão para descriptografia, configure a sessão com o modo AWS_CRYPTOSDK_DECRYPT.

Depois de criar uma sessão com um token de autenticação, você poderá liberar sua referência ao token de autenticação usando o método fornecido pelo SDK. A sessão mantém uma referência ao objeto token de autenticação durante sua vida útil, e a sessão e o token de autenticação são liberados quando você destrói a sessão. Essa técnica de contagem de referência ajuda a evitar vazamentos de memória e a evitar que os objetos sejam liberados enquanto estão em uso.

struct aws_cryptosdk_session *session = aws_cryptosdk_session_new_from_keyring(alloc, AWS_CRYPTOSDK_DECRYPT, kms_keyring); // When you add the keyring to the session, release the keyring object aws_cryptosdk_keyring_release(kms_keyring);
Etapa 3 Desencripte a cadeia.

Para descriptografar a string, use o método aws_cryptosdk_session_process com a sessão configurada para descriptografia.

Na descriptografia, os campos em texto cifrado são campos de entrada, e os campos em texto simples são campos de saída. O campo ciphertext_input contém a mensagem criptografada retornada pelo método de criptografia. Quando o processamento for concluído, o campo plaintext_output conterá a string em texto simples (descriptografada).

size_t ciphertext_consumed_output; aws_cryptosdk_session_process(session, plaintext_output, plaintext_buf_sz_output, plaintext_len_output, ciphertext_input, ciphertext_len_input, &ciphertext_consumed_output)
Etapa 4. Confirme que o processo está concluído.

Após a descriptografia, o código executa aws_cryptosdk_session_is_done, o que confirma que o processamento da sessão foi concluído e a assinatura foi verificada. Se retornar FALSE, o código destruirá a sessão para evitar vazamentos de memória. Além disso, se restar texto cifrado no buffer, o exemplo será interrompido.

Certifique-se de que a sessão esteja concluída, principalmente na descriptografia. O texto simples inteiro pode ser retornado antes da verificação da assinatura.

if (!aws_cryptosdk_session_is_done(session)) { aws_cryptosdk_session_destroy(session); return 13; } if (ciphertext_consumed != ciphertext_len) abort();
Etapa 5. Verifique o contexto da encriptação.

Verifique se o contexto de criptografia real — o que foi usado para descriptografar a mensagem — contém o contexto de criptografia fornecido ao criptografar a mensagem. O contexto de criptografia real pode incluir pares extras porque o gerenciador de materiais criptográficos (CMM) pode adicionar pares ao contexto de criptografia fornecido antes de criptografar a mensagem.

No AWS Encryption SDK para C, você não precisa fornecer um contexto de criptografia ao descriptografar porque o contexto é incluído na mensagem criptografada retornada pelo SDK. No entanto, antes que a mensagem em texto simples seja retornada, sua função de descriptografia deve verificar se todos os pares no contexto de criptografia fornecido aparecem no contexto que foi usado para descriptografar a mensagem.

Primeiro, obtenha um ponteiro somente leitura para a tabela de hash na sessão. Essa tabela de hash contém o contexto de criptografia que foi usado para descriptografar a mensagem.

const struct aws_hash_table *session_enc_ctx = aws_cryptosdk_session_get_enc_ctx_ptr(session);

Depois, percorra o contexto na tabela de hash my_enc_ctx que você copiou ao efetuar a criptografia. Verifique se cada par na tabela de hash my_enc_ctx que foi usada para efetuar a criptografia aparece na tabela de hash session_enc_ctx que foi usada para efetuar a descriptografia. Se alguma chave estiver ausente ou se essa chave tiver um valor diferente, interrompa o processamento e escreva uma mensagem de erro.

for (struct aws_hash_iter iter = aws_hash_iter_begin(my_enc_ctx); !aws_hash_iter_done(&iter); aws_hash_iter_next(&iter)) { struct aws_hash_element *session_enc_ctx_kv_pair; aws_hash_table_find(session_enc_ctx, iter.element.key, &session_enc_ctx_kv_pair) if (!session_enc_ctx_kv_pair || !aws_string_eq( (struct aws_string *)iter.element.value, (struct aws_string *)session_enc_ctx_kv_pair->value)) { fprintf(stderr, "Wrong encryption context!\n"); abort(); } }
Limpe a sessão.

Depois de verificar o contexto de criptografia, destrua a sessão. Como sempre, você pode reutilizar a sessão. Se precisar reconfigurá-la, use o método aws_cryptosdk_session_reset.

aws_cryptosdk_session_destroy(session);