nRF52

nRF52840 ECC 공개 키 기반 암호화의 원리와 장점

임베디드 친구 2025. 2. 20. 15:53
728x90
반응형

ECC 공개 키 기반 암호화의 원리와 장점

1. ECC(타원 곡선 암호)의 개요

ECC(Elliptic Curve Cryptography)는 타원 곡선의 수학적 성질을 이용한 비대칭 키 암호화 방식입니다. 비대칭 키 암호화는 하나의 키로 데이터를 암호화하고, 다른 키로 복호화하는 방식으로, 주로 공개 키개인 키를 사용합니다. ECC는 기존 RSA와 같은 비대칭 키 방식보다 더 작은 키 크기로 유사한 수준의 보안을 제공하는 특징이 있습니다.

타원 곡선은 다음과 같은 형태의 방정식으로 표현됩니다.

$$
y^2 = x^3 + ax + b
$$

여기서 $a$와 $b$는 타원 곡선을 정의하는 상수입니다. 이러한 타원 곡선 위의 점들과 특정 연산을 기반으로 ECC 알고리즘이 동작합니다.

2. ECC의 주요 원리

ECC의 기본 원리는 점 덧셈(Point Addition)점 곱셈(Point Multiplication)에 기반합니다.

  1. 점 덧셈(Point Addition): 타원 곡선 위의 두 점 $P$와 $Q$가 있을 때, 이 두 점을 더한 결과 $R = P + Q$도 타원 곡선 위에 존재합니다.
  2. 점 곱셈(Point Multiplication): 특정 점 $P$와 스칼라 값 $k$가 있을 때, $kP$는 $P$를 $k$번 덧셈한 결과입니다. 이는 $P + P + ... + P$와 동일한 의미입니다.

이 과정에서 단방향성이 중요한 역할을 합니다. 점 곱셈을 통해 $Q = kP$를 구하는 것은 간단하지만, $Q$가 주어졌을 때 $k$를 찾는 것은 이산 로그 문제로 인해 매우 어렵습니다. 이러한 어려움이 ECC의 보안성을 보장합니다.

3. ECC 공개 키 암호화 과정

ECC 기반의 공개 키 암호화는 다음과 같은 과정으로 진행됩니다.

1) 키 생성

  • 개인 키(Private Key): 난수로 생성된 256비트 정수 $d$.
  • 공개 키(Public Key): 개인 키와 타원 곡선의 기준점 $G$를 곱하여 얻은 $Q = dG$.

2) 데이터 암호화

송신자가 수신자의 공개 키 $Q$를 사용하여 데이터를 암호화하는 과정은 다음과 같습니다.

  1. 난수 $k$ 생성
  2. 두 개의 값 생성:
    • $C1 = kG$ : 타원 곡선상의 점
    • $C2 = P + kQ$ : 데이터 $P$와 수신자의 공개 키를 이용한 점
  3. $C1$과 $C2$를 암호문으로 전송

3) 데이터 복호화

수신자는 자신의 개인 키 $d$를 사용하여 복호화합니다.

  1. $C1$과 $C2$ 수신
  2. $C2 - dC1$을 통해 원래 데이터 $P$ 복원

여기서 $dC1 = d(kG) = k(dG) = kQ$이므로, $C2 - kQ$는 원본 데이터 $P$와 같습니다.

4. ECC의 장점

ECC는 다음과 같은 주요 장점을 제공합니다.

  1. 높은 보안성:
    • ECC는 RSA와 비교하여 동일한 보안 수준을 유지하면서 더 작은 키 크기를 사용합니다. 예를 들어, 256비트 ECC 키는 3072비트 RSA 키와 유사한 수준의 보안을 제공합니다.
  2. 성능 및 효율성:
    • 작은 키 크기 덕분에 연산 속도가 빠르고, 메모리와 전력 소비가 적습니다.
  3. 저전력 환경에 적합:
    • IoT 장치, 스마트카드, 임베디드 시스템과 같이 자원이 제한된 환경에서도 효과적으로 사용됩니다.
  4. 간편한 키 관리:
    • 키 크기가 작아 전송과 저장이 용이하며, 네트워크 부하를 줄일 수 있습니다.

5. nRF52 SDK를 활용한 ECC 키 쌍 생성 및 데이터 암호화

nRF52840과 nRF5 SDK에서는 nrf_crypto 라이브러리를 이용해 ECC 키 생성과 데이터 암호화를 구현할 수 있습니다. 아래는 예제 코드입니다.

(1) 키 쌍 생성

#include "nrf_crypto.h"
#include "nrf_log.h"

void generate_ecc_keypair(void) {
    ret_code_t ret;
    nrf_crypto_ecc_key_pair_generate_context_t keygen_context;
    nrf_crypto_ecc_public_key_t public_key;
    nrf_crypto_ecc_private_key_t private_key;

    // ECC 키 쌍 생성
    ret = nrf_crypto_ecc_key_pair_generate(&keygen_context,
                                          &g_nrf_crypto_ecc_secp256r1_curve_info,
                                          &private_key,
                                          &public_key);
    if (ret != NRF_SUCCESS) {
        NRF_LOG_ERROR("ECC 키 생성 실패: %d", ret);
        return;
    }

    NRF_LOG_INFO("ECC 키 쌍이 성공적으로 생성되었습니다.");

    // 메모리 해제
    nrf_crypto_ecc_private_key_free(&private_key);
    nrf_crypto_ecc_public_key_free(&public_key);
}

(2) 데이터 암호화

void encrypt_data(const uint8_t *input, size_t input_len) {
    ret_code_t ret;
    nrf_crypto_ecc_public_key_t public_key;
    uint8_t encrypted_data[128];
    size_t encrypted_len = sizeof(encrypted_data);

    // ECC 공개 키 기반 데이터 암호화
    ret = nrf_crypto_ecc_public_key_from_raw(&g_nrf_crypto_ecc_secp256r1_curve_info,
                                             public_key_data,
                                             sizeof(public_key_data),
                                             &public_key);

    if (ret != NRF_SUCCESS) {
        NRF_LOG_ERROR("공개 키 불러오기 실패: %d", ret);
        return;
    }

    ret = nrf_crypto_ecdh_compute_shared_secret(&public_key,
                                                &private_key,
                                                encrypted_data,
                                                &encrypted_len);

    if (ret != NRF_SUCCESS) {
        NRF_LOG_ERROR("암호화 실패: %d", ret);
        return;
    }

    NRF_LOG_INFO("데이터가 성공적으로 암호화되었습니다.");
}

(3) 데이터 복호화

void decrypt_data(const uint8_t *encrypted_data, size_t encrypted_len) {
    ret_code_t ret;
    uint8_t decrypted_data[128];
    size_t decrypted_len = sizeof(decrypted_data);

    ret = nrf_crypto_ecdh_compute_shared_secret(&public_key,
                                                &private_key,
                                                decrypted_data,
                                                &decrypted_len);

    if (ret != NRF_SUCCESS) {
        NRF_LOG_ERROR("복호화 실패: %d", ret);
        return;
    }

    NRF_LOG_INFO("복호화된 데이터: %s", decrypted_data);
}

6. 결론

ECC는 강력한 보안성과 효율성을 제공하는 비대칭 암호화 방식으로, 특히 자원이 제한된 IoT 환경에서 적합합니다. nRF52840과 nRF5 SDK를 이용하면 쉽게 ECC 기반의 키 쌍을 생성하고, 데이터를 안전하게 암호화 및 복호화할 수 있습니다.

본 포스팅에서는 ECC의 기본 원리와 장점, nRF52 SDK를 이용한 키 생성, 암호화, 복호화 방법을 소개했습니다. 실무에서 ECC를 적용할 때는 키 관리와 성능 최적화에도 주의가 필요합니다.

반응형