AWS Encryption SDK for C 예제 - AWS Encryption SDK

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

AWS Encryption SDK for C 예제

다음 예제에서는 AWS Encryption SDK for C를 사용하여 데이터를 암호화 및 복호화하는 방법을 보여줍니다.

이 섹션의 예제에서는 2.0.x 이상 버전의 AWS Encryption SDK for C를 사용하는 방법을 보여줍니다. 이하 버전을 사용하는 예제는 GitHub의 aws-encryption-sdk-c 리포지토리 리포지토리의 릴리스 목록에서 해당하는 릴리스를 찾을 수 있습니다.

AWS Encryption SDK for C를 설치하고 빌드할 경우 이러한 예제 및 기타 예제의 소스 코드는 examples 하위 디렉터리에 포함되며, build 디렉터리로 컴파일되고 빌드됩니다. GitHub의 aws-encryption-sdk-c 리포지토리의 예제 하위 디렉터리에서도 해당 예제를 찾을 수 있습니다.

문자열 암호화 및 복호화

다음 예제에서는 AWS Encryption SDK for C를 사용하여 문자열을 암호화 및 복호화하는 방법을 보여줍니다.

이 예제에서는 AWS Key Management Service(AWS KMS)의 AWS KMS key를 사용하여 데이터 키를 생성하고 암호화하는 키링의 일종인 AWS KMS 키링을 살펴봅니다. 이 예제에는 C++로 작성된 코드가 포함되어 있습니다. AWS Encryption SDK for C는 AWS KMS 키링을 사용할 때 AWS KMS를 호출하기 위해 AWS SDK for C++가 필요합니다. 원시 AES 키링, 원시 RSA 키링 또는 AWS KMS 키링이 포함되지 않은 멀티 키링과 같이 AWS KMS와 상호 작용하지 않는 키링을 사용하는 경우 AWS SDK for C++는 필요하지 않습니다.

AWS KMS key 생성에 대한 도움말은 AWS Key Management Service 개발자 가이드키 생성을 참조하세요. AWS KMS 키링에서 AWS KMS keys를 식별하는 데 도움이 필요하면 AWS KMS keysAWS KMS 키링에서 식별 섹션을 참조하세요.

전체 코드 샘플 보기: string.cpp

문자열 암호화

이 예제의 첫 번째 부분에서는 하나의 AWS KMS key가 있는 AWS KMS 키링을 사용하여 일반 텍스트 문자열을 암호화합니다.

1단계: 오류 문자열을 로드합니다.

C 또는 C++ 코드에서 aws_cryptosdk_load_error_strings() 메서드를 호출합니다. 이 메서드는 디버깅에 매우 유용한 오류 정보를 로드합니다.

main 메서드에서와 같이 한 번만 호출하면 됩니다.

/* Load error strings for debugging */ aws_cryptosdk_load_error_strings();
2단계: 키링을 구성합니다.

암호화를 위한 AWS KMS 키링을 생성합니다. 이 예제의 키링은 한 개의 AWS KMS key로 구성되지만 다른 AWS 리전 및 다른 계정의 AWS KMS keys를 포함하여 여러 개의 AWS KMS keys로 AWS KMS 키링을 구성할 수 있습니다.

AWS Encryption SDK for C에서 암호화 키링의 AWS KMS key를 식별하려면 키 ARN 또는 별칭 ARN을 지정합니다. 복호화 키링에서는 키 ARN을 사용해야 합니다. 자세한 내용은 AWS KMS keysAWS KMS 키링에서 식별 섹션을 참조하세요.

AWS KMS keysAWS KMS 키링에서 식별

여러 AWS KMS keys가 있는 키링을 생성하는 경우 일반 텍스트 데이터 키를 생성하고 암호화하는 데 사용되는 AWS KMS key와, 동일한 일반 텍스트 데이터 키를 암호화하는 추가 AWS KMS keys 배열(선택 사항)을 지정합니다. 이 예에서는 생성기 AWS KMS key만 지정합니다.

이 코드를 실행하기 전에 예제 키 ARN을 유효한 키로 바꿉니다.

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);
3단계: 세션을 생성합니다.

할당자, 모드 열거자, 키링을 사용하여 세션을 생성합니다.

모든 세션에는 모드가 필요합니다. 암호화하려면 AWS_CRYPTOSDK_ENCRYPT, 복호화하려면 AWS_CRYPTOSDK_DECRYPT 중 하나를 선택해야 합니다. 기존 세션의 모드를 변경하려면 aws_cryptosdk_session_reset 메서드를 사용합니다.

키링으로 세션을 생성한 후, SDK가 제공하는 메서드를 사용하여 키링에 대한 참조를 릴리스할 수 있습니다. 세션은 수명 기간 동안 키링 객체에 대한 참조를 유지합니다. 세션을 삭제하면 키링 및 세션 객체에 대한 참조가 릴리스됩니다. 이 참조 카운트 기술은 메모리 누수를 방지하고 객체가 사용 중일 때 객체가 릴리스되지 않도록 도와줍니다.

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);
4단계: 암호화 컨텍스트를 설정합니다.

암호화 컨텍스트는 비밀이 아닌 임의의 추가 인증 데이터입니다. 암호화에 암호화 컨텍스트를 제공하면 AWS Encryption SDK는 암호화 컨텍스트를 사이퍼텍스트에 암호화 방식으로 바인딩하여 데이터를 복호화하는 데 동일한 암호화 컨텍스트가 필요하도록 합니다. 암호화 컨텍스트를 사용하는 것은 선택 사항이지만 권장되는 모범 사례입니다.

먼저 암호화 컨텍스트 문자열을 포함하는 해시 테이블을 생성합니다.

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

세션에서 암호화 컨텍스트에 대한 변경 가능한 포인터를 가져옵니다. 그런 다음 aws_cryptosdk_enc_ctx_clone 함수를 사용하여 암호화 컨텍스트를 세션에 복사합니다. 이 복사본은 데이터를 복호화한 후 값을 검증할 수 있도록 my_enc_ctx에 보관됩니다.

암호화 컨텍스트는 세션 프로세스 함수에 전달되는 파라미터가 아니라 세션의 일부입니다. 이렇게 하면 전체 메시지를 암호화하기 위해 세션 프로세스 함수를 여러 번 호출하더라도 메시지의 모든 세그먼트에 동일한 암호화 컨텍스트가 사용되도록 합니다.

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)
5단계: 문자열을 암호화합니다.

일반 텍스트 문자열을 암호화하려면 세션이 암호화 모드인 상태에서 aws_cryptosdk_session_process_full 메서드를 사용합니다. 이 메서드는 AWS Encryption SDK 버전 1.9.x 및 2.2.x에 도입되었으며, 비스트리밍 암호화 및 복호화를 위해 설계되었습니다. 스트리밍 데이터를 처리하려면 aws_cryptosdk_session_process를 루프에서 호출합니다.

암호화할 때 일반 텍스트 필드는 입력 필드이고 사이퍼텍스트 필드는 출력 필드입니다. 처리가 완료되면 실제 사이퍼텍스트, 암호화된 데이터 키, 암호화 컨텍스트를 비롯한 암호화된 메시지ciphertext_output 필드에 포함됩니다. 암호화된 이 메시지는 지원되는 프로그래밍 언어의 AWS Encryption SDK를 사용하여 복호화할 수 있습니다.

/* 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; }
6단계: 세션을 정리합니다.

마지막 단계에서는 CMM 및 키링에 대한 참조를 포함하여 세션을 삭제합니다.

원하는 경우 세션을 삭제하는 대신 동일한 키링과 CMM으로 세션을 재사용하여 문자열을 복호화하거나 다른 메시지를 암호화 또는 복호화할 수 있습니다. 세션을 복호화에 사용하려면 aws_cryptosdk_session_reset 메서드를 사용하여 모드를 AWS_CRYPTOSDK_DECRYPT로 변경합니다.

문자열 복호화

이 예제의 두 번째 부분에서는 원본 문자열의 사이퍼텍스트가 포함된 암호화된 메시지를 복호화합니다.

1단계: 오류 문자열을 로드합니다.

C 또는 C++ 코드에서 aws_cryptosdk_load_error_strings() 메서드를 호출합니다. 이 메서드는 디버깅에 매우 유용한 오류 정보를 로드합니다.

main 메서드에서와 같이 한 번만 호출하면 됩니다.

/* Load error strings for debugging */ aws_cryptosdk_load_error_strings();
2단계: 키링을 구성합니다.

AWS KMS에서 데이터를 복호화할 때는 암호화 API가 반환한 암호화된 메시지를 전달합니다. 복호화 API는 입력으로 AWS KMS key를 사용하지 않습니다. 대신 AWS KMS는 동일한 AWS KMS key를 사용하여 암호화에 사용된 사이퍼텍스트를 복호화합니다. 하지만 AWS Encryption SDK를 사용하면 암호화 및 복호화 시 AWS KMS keys가 포함된 AWS KMS 키링을 지정할 수 있습니다.

복호화 시, 암호화된 메시지를 복호화하는 데 사용하려는 AWS KMS keys로만 키링을 구성할 수 있습니다. 예를 들어 해당 조직의 특정 역할이 사용하는 AWS KMS key만으로 키링을 생성할 수 있습니다. AWS Encryption SDK는 복호화 키링에 AWS KMS key가 없으면 사용하지 않습니다. 사용자가 제공하는 키링의 AWS KMS keys를 사용하여 암호화된 데이터 키를 SDK가 복호화할 수 없는 경우, 키링의 AWS KMS keys가 데이터 키를 암호화하는 데 사용되지 않았거나, 호출자가 복호화를 위해 키링의 AWS KMS keys를 사용할 권한이 없기 때문에 복호화 호출이 실패합니다.

복호화 키링에 AWS KMS key를 지정할 때는 키 ARN을 사용해야 합니다. 별칭 ARN은 암호화 키링에서만 허용됩니다. AWS KMS 키링에서 AWS KMS keys를 식별하는 데 도움이 필요하면 AWS KMS keysAWS KMS 키링에서 식별 섹션을 참조하세요.

이 예에서는 문자열을 암호화하는 데 사용된 것과 동일한 AWS KMS key로 구성된 키링을 지정합니다. 이 코드를 실행하기 전에 예제 키 ARN을 유효한 키로 바꿉니다.

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);
3단계: 세션을 생성합니다.

할당자와 키링을 사용하여 세션을 생성합니다. 복호화를 위한 세션을 구성하려면 AWS_CRYPTOSDK_DECRYPT 모드를 사용하여 세션을 구성합니다.

키링으로 세션을 생성한 후, SDK가 제공하는 메서드를 사용하여 키링에 대한 참조를 릴리스할 수 있습니다. 세션은 수명 동안 키링 객체에 대한 참조를 유지하며, 세션과 키링은 세션을 삭제할 때 릴리스됩니다. 이 참조 카운트 기술은 메모리 누수를 방지하고 객체가 사용 중일 때 객체가 릴리스되지 않도록 도와줍니다.

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);
4단계: 문자열을 복호화합니다.

문자열을 복호화하려면 복호화를 위해 구성된 세션에서 aws_cryptosdk_session_process_full 메서드를 사용합니다. 이 메서드는 AWS Encryption SDK 버전 1.9.x 및 2.2.x에 도입되었으며, 비스트리밍 암호화 및 복호화를 위해 설계되었습니다. 스트리밍 데이터를 처리하려면 aws_cryptosdk_session_process를 루프에서 호출합니다.

복호화 시 사이퍼텍스트 필드는 입력 필드이고 일반 텍스트 필드는 출력 필드입니다. ciphertext_input 필드에는 암호화 메서드가 반환한 암호화된 메시지가 있습니다. 처리가 완료되면 plaintext_output 필드에 일반 텍스트(복호화된) 문자열이 포함됩니다.

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; }
5단계: 암호화 컨텍스트를 확인합니다.

메시지를 복호화하는 데 사용된 실제 암호화 컨텍스트에 메시지를 암호화할 때 제공한 암호화 컨텍스트가 포함되어 있는지 확인하세요. 암호화 구성 요소 관리자(CMM)가 메시지를 암호화하기 전에 제공된 암호화 컨텍스트에 페어를 추가할 수 있으므로 실제 암호화 컨텍스트에 추가 페어가 포함될 수 있습니다.

AWS Encryption SDK for C에서는 복호화 시 암호화 컨텍스트를 제공할 필요가 없습니다. SDK가 반환하는 암호화된 메시지에 암호화 컨텍스트가 포함되기 때문입니다. 하지만 복호화 함수는 일반 텍스트 메시지를 반환하기 전에 제공된 암호화 컨텍스트의 모든 페어가 메시지를 복호화하는 데 사용된 암호화 컨텍스트에 나타나는지 확인해야 합니다.

먼저 세션의 해시 테이블에 대한 읽기 전용 포인터를 가져옵니다. 이 해시 테이블에는 메시지를 복호화하는 데 사용된 암호화 컨텍스트가 포함되어 있습니다.

const struct aws_hash_table *session_enc_ctx = aws_cryptosdk_session_get_enc_ctx_ptr(session);

그런 다음 암호화할 때 복사한 my_enc_ctx 해시 테이블에서 암호화 컨텍스트를 반복합니다. 암호화에 사용된 my_enc_ctx 해시 테이블의 각 페어가 복호화에 사용된 session_enc_ctx 해시 테이블에 나타나는지 확인합니다. 누락된 키가 있거나 해당 키의 값이 다른 경우 처리를 중지하고 오류 메시지를 작성합니다.

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(); } }
6단계: 세션을 정리합니다.

암호화 컨텍스트를 확인한 후 세션을 삭제하거나 재사용할 수 있습니다. 세션을 재구성해야 하는 경우 aws_cryptosdk_session_reset 메서드를 사용합니다.

aws_cryptosdk_session_destroy(session);