Ejemplos del SDK de cifrado de AWS para C - AWS Encryption SDK

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Ejemplos del SDK de cifrado de AWS para C

En los siguientes ejemplos se muestra cómo utilizar el SDK de cifrado de AWS para C para cifrar y descifrar datos.

Los ejemplos en esta sección muestran cómo usar las versiones 2.0.x y posteriores del SDK de cifrado de AWS para C. Para ver ejemplos que usan versiones anteriores, busque su versión en la lista de Versiones del repositorio aws-encryption-sdk-c repository en GitHub.

Cuando se instala y compila el SDK de cifrado de AWS para C, el código fuente para este y otros ejemplos se incluye en el subdirectorio examples y se compilan en el directorio build. También los encontrará en el subdirectorio examples del repositorio aws-encryption-sdk-c en GitHub.

Cifrado y descifrado de cadenas

En el ejemplo siguiente se muestra cómo utilizar el SDK de cifrado de AWS para C para cifrar y descifrar una cadena.

Este ejemplo muestra el llavero AWS KMS, un tipo de llavero que utiliza una AWS KMS key en AWS Key Management Service (AWS KMS) para generar y cifrar claves de datos. El ejemplo incluye código escrito en C++. El SDK de cifrado de AWS para C requiere que AWS SDK for C++ llame a AWS KMS cuando se utilizan llaveros AWS KMS. Si utiliza un llavero que no interactúa con AWS KMS, como un llavero AES sin procesar, un llavero RSA sin procesar o un llavero múltiple que no incluye un llavero AWS KMS, no es obligatorio el AWS SDK for C++.

Para obtener ayuda acerca de cómo crear una AWS KMS key, consulte Creación de claves en la Guía para desarrolladores de AWS Key Management Service. Si necesita ayuda para identificar AWS KMS keys en un llavero AWS KMS, consulte Identificarse AWS KMS keys en un AWS KMS llavero.

Vea la muestra de código completa: string.cpp

Cifrado de una cadena

La primera parte de este ejemplo utiliza un llavero AWS KMS con un AWS KMS key para cifrar una cadena de texto no cifrado.

Paso 1. Cargue cadenas de error.

Llame al método aws_cryptosdk_load_error_strings() en su código C o C++. Carga información de error que es muy útil para la depuración.

Solo necesita llamarlo una vez, por ejemplo, en su método main.

/* Load error strings for debugging */ aws_cryptosdk_load_error_strings();
Paso 2: Crear el llavero.

Cree un llavero AWS KMS para cifrado. El llavero de este ejemplo está configurado con un AWS KMS key, pero puede configurar un AWS KMS con varios AWS KMS keys, incluido AWS KMS keys en distintos Regiones de AWS y cuentas diferentes.

Para identificar un AWS KMS key en un llavero de cifrado en SDK de cifrado de AWS para C, especifique un ARN de clave o un ARN de alias. En un llavero de descifrado, debe usar un ARN de clave. Para obtener más información, consulte Identificarse AWS KMS keys en un AWS KMS llavero.

Identificarse AWS KMS keys en un AWS KMS llavero

Al crear un llavero con varios AWS KMS keys, especifique el AWS KMS key que debe utilizarse para generar y cifrar la clave de datos en texto no cifrado y una matriz opcional de AWS KMS keys adicionales que cifren la misma clave de datos en texto no cifrado. En este caso, solo especifica el AWS KMS key generador.

Antes de ejecutar este código, reemplace el ARN de claves de ejemplo por uno 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);
Paso 3: Crear una sesión.

Cree una sesión. Para ello, use el asignador, un enumerador de modos y el llavero.

Cada sesión requiere un modo: bien AWS_CRYPTOSDK_ENCRYPT para cifrar o AWS_CRYPTOSDK_DECRYPT para descifrar. Para cambiar el modo de una sesión existente, utilice el método aws_cryptosdk_session_reset.

Después de crear una sesión con el llavero, puede liberar la referencia al llavero con el método que el SDK proporciona. La sesión conserva una referencia al objeto llavero durante su vida útil. Las referencias al llavero y a los objetos de sesión se liberan cuando se destruye la sesión. Esta técnica de recuento de referencias ayuda a evitar fugas de memoria y que los objetos se liberen mientras están en uso.

struct aws_cryptosdk_session *session = aws_cryptosdk_session_new_from_keyring_2(alloc, AWS_CRYPTOSDK_ENCRYPT, kms_keyring); /* When you add the keyring to the session, release the keyring object */ aws_cryptosdk_keyring_release(kms_keyring);
Paso 4: Establecer el contexto de cifrado.

Un contexto de cifrado son datos autenticados adicionales que son arbitrarios y no son secretos. Cuando se proporciona un contexto de cifrado en el cifrado, el AWS Encryption SDK vincula criptográficamente el contexto de cifrado al texto cifrado para que se requiera el mismo contexto de cifrado para descifrar los datos. El uso de un contexto de cifrado es opcional, pero es una práctica recomendada que le aconsejamos.

En primer lugar, cree una tabla hash que incluya las cadenas del contexto de cifrado.

/* 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)

Obtenga un puntero mutable al contexto de cifrado en la sesión. A continuación, utilice la función aws_cryptosdk_enc_ctx_clone para copiar el contexto de cifrado en la sesión. Conserve la copia en my_enc_ctx para poder validar el valor después de descifrar los datos.

El contexto de cifrado forma parte de la sesión, no es un parámetro transferido a la función de proceso de la sesión. Esto garantiza que se utilice el mismo contexto de cifrado para cada segmento de un mensaje, incluso si se llama varias veces a la función de proceso de la sesión para cifrar todo el mensaje.

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)
Paso 5: Cifrar la cadena.

Para cifrar la cadena de texto no cifrado, utilice el método aws_cryptosdk_session_process_full con la sesión en modo de cifrado. Este método introducido en las versiones 1.9.x y 2.2.x de AWS Encryption SDK está diseñado para el cifrado y el descifrado sin streaming. Para gestionar el streaming de datos, utilice el comando aws_cryptosdk_session_process en un bucle.

A la hora de cifrar, los campos de texto no cifrado son campos de entrada; los campos de texto no cifrado son campos de salida. Cuando se completa el procesamiento, el campo ciphertext_output contiene el mensaje cifrado, incluido el texto no cifrado real, las claves de datos cifrados y el contexto de cifrado. Puede descifrar este mensaje cifrado con la ayuda del AWS Encryption SDK en cualquier lenguaje de programación admitido.

/* Gets the length of the plaintext that the session processed */ size_t ciphertext_len_output; if (AWS_OP_SUCCESS != aws_cryptosdk_session_process_full(session, ciphertext_output, ciphertext_buf_sz_output, &ciphertext_len_output, plaintext_input, plaintext_len_input)) { aws_cryptosdk_session_destroy(session); return 8; }
Paso 6: Limpiar la sesión.

El paso final destruye la sesión, incluidas las referencias al CMM y al llavero.

Si lo prefiere, en lugar de destruir la sesión, puede reutilizarla con el mismo llavero y CMM para descifrar la cadena o para cifrar o descifrar otros mensajes. Para utilizar la sesión para descifrado, utilice el método aws_cryptosdk_session_reset para cambiar el modo a AWS_CRYPTOSDK_DECRYPT.

Descifrado de una cadena

La segunda parte de este ejemplo descifra un mensaje cifrado que contiene el texto cifrado de la cadena original.

Paso 1: Cargar las cadenas de error.

Llame al método aws_cryptosdk_load_error_strings() en su código C o C++. Carga información de error que es muy útil para la depuración.

Solo necesita llamarlo una vez, por ejemplo, en su método main.

/* Load error strings for debugging */ aws_cryptosdk_load_error_strings();
Paso 2: Crear el llavero.

Cuando se descifran datos en AWS KMS, transfiere el mensaje cifrado que ha devuelto la API de cifrado. La API de descifrado no toma un AWS KMS key como entrada. En su lugar, AWS KMS utiliza para descifrar el texto cifrado la misma AWS KMS key que usó para cifrarlo. Sin embargo, el AWS Encryption SDK permite especificar un llavero AWS KMS con AWS KMS keys en el cifrado y descifrado.

Al descifrar, puede configurar un llavero con solo las AWS KMS keys que desea utilizar para descifrar el mensaje cifrado. Por ejemplo, es posible que quiera crear un llavero con solo la AWS KMS key que un rol concreto de su organización usa. El AWS Encryption SDK nunca utilizará un AWS KMS key a menos que aparezca en el llavero de descifrado. Si el SDK no puede descifrar las claves de datos cifradas mediante las AWS KMS keys del llavero que se proporcione, bien porque no se utilizó ninguna de las AWS KMS keys del llavero para cifrar las claves de datos o porque el intermediario no tiene permiso para utilizar las AWS KMS keys del llavero para descifrar, el descifrado devuelve un error.

Cuando especifique un AWS KMS key para un llavero de descifrado, debe usar su ARN de clave. Los ARN de alias solo se permiten en los llaveros de cifrado. Si necesita ayuda para identificar AWS KMS keys en un llavero AWS KMS, consulte Identificarse AWS KMS keys en un AWS KMS llavero.

En este ejemplo, especificamos un llavero que se configuró con la misma AWS KMS key que se utilizó para cifrar la cadena. Antes de ejecutar este código, reemplace el ARN de claves de ejemplo por uno 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);
Paso 3: Crear una sesión.

Cree una sesión con el asignador y el llavero. Para configurar la sesión para descifrado, configure la sesión con el modo AWS_CRYPTOSDK_DECRYPT.

Después de crear una sesión con un llavero, puede liberar la referencia al llavero con el método que el SDK proporciona. La sesión conserva una referencia al objeto de llavero durante su ciclo de vida y tanto la sesión como el llavero se liberan cuando se destruye la sesión. Esta técnica de recuento de referencias ayuda a evitar fugas de memoria y que los objetos se liberen mientras están en uso.

struct aws_cryptosdk_session *session = aws_cryptosdk_session_new_from_keyring_2(alloc, AWS_CRYPTOSDK_DECRYPT, kms_keyring); /* When you add the keyring to the session, release the keyring object */ aws_cryptosdk_keyring_release(kms_keyring);
Paso 4: Descifrar la cadena.

Para descifrar la cadena, utilice el método aws_cryptosdk_session_process_full con la sesión que está configurada para descifrado. Este método introducido en las versiones 1.9.x y 2.2.x de AWS Encryption SDK está diseñado para el cifrado y el descifrado sin streaming. Para gestionar el streaming de datos, utilice el comando aws_cryptosdk_session_process en un bucle.

Al descifrar, los campos de texto cifrado son campos de entrada y los campos de texto no cifrado son campos de salida. El campo ciphertext_input mantiene el mensaje cifrado que devolvió el método de cifrado. Cuando el procesamiento está completo, el campo plaintext_output contiene la cadena de texto no cifrado (descifrado).

size_t plaintext_len_output; if (AWS_OP_SUCCESS != aws_cryptosdk_session_process_full(session, plaintext_output, plaintext_buf_sz_output, &plaintext_len_output, ciphertext_input, ciphertext_len_input)) { aws_cryptosdk_session_destroy(session); return 13; }
Paso 5: Verificar el contexto de cifrado.

Asegúrese de que el contexto de cifrado real (el que se utilizó para descifrar el mensaje) contenga el contexto de cifrado que proporcionó al cifrar el mensaje. El contexto de cifrado real podría incluir pares adicionales, ya que el administrador de materiales criptográficos (CMM) puede añadir pares al contexto de cifrado proporcionado antes de cifrar el mensaje.

En el SDK de cifrado de AWS para C, no es obligatorio proporcionar un contexto de cifrado al descifrar, ya que dicho contexto está incluido en el mensaje cifrado que devuelve el SDK. Pero, antes de que devuelva el mensaje de texto no cifrado, la función de descifrado debería verificar que todas las parejas en el contexto de cifrado proporcionado aparezcan en el contexto de cifrado que se utilizó para descifrar el mensaje.

En primer lugar, obtenga un puntero de solo lectura a la tabla hash de la sesión. Esta tabla hash contiene el contexto de cifrado que se utilizó para descifrar el mensaje.

const struct aws_hash_table *session_enc_ctx = aws_cryptosdk_session_get_enc_ctx_ptr(session);

A continuación, ejecute un bucle en el contexto de cifrado en la tabla hash my_enc_ctx que copió al realizar el cifrado. Verifique que cada para de la tabla hash my_enc_ctx que se utilizó para cifrar aparece en la tabla hash session_enc_ctx que se utilizó para descifrar. Si falta alguna clave o dicha clave tiene un valor distinto, detenga el procesamiento y escriba un mensaje de error.

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(); } }
Paso 6: Limpiar la sesión.

Después de verificar el contexto de cifrado, puede destruir la sesión o reutilizarla. Si tiene que reconfigurar la sesión, utilice el método aws_cryptosdk_session_reset.

aws_cryptosdk_session_destroy(session);