nRF52

nRF52840 True Random Number Generator를 활용한 안전한 난수 생성 및 키 관리

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

True Random Number Generator를 활용한 안전한 난수 생성 및 키 관리

nRF52840과 같은 고급 임베디드 디바이스에서는 보안성을 높이기 위해 난수 생성과 키 관리는 필수적인 요소입니다. 이 글에서는 nRF52840의 True Random Number Generator(TRNG)를 활용한 안전한 난수 생성 방법과, nRF52 SDK를 활용해 플래시 메모리와 RAM을 이용한 안전한 키 저장 및 관리 방법에 대해 설명하겠습니다.


1. True Random Number Generator(TRNG)란?

TRNG(True Random Number Generator)는 하드웨어 기반의 난수 생성기로, 전자 소자의 열 잡음이나 기타 물리적 현상을 활용해 예측 불가능한 난수를 생성합니다. 소프트웨어 기반의 의사 난수 생성기(PRNG, Pseudo-Random Number Generator)와는 달리, TRNG는 초기 시드 값과 관계없이 완전히 무작위적인 값을 생성합니다.

nRF52840은 내장된 TRNG 하드웨어 모듈을 제공하며, 이는 보안 프로토콜, 키 생성, 무작위 값 생성 등 다양한 보안 작업에 활용됩니다.

TRNG의 특징

  • 무작위성: 물리적 현상을 기반으로 하기 때문에 예측이 불가능합니다.
  • 보안성: 암호화 키와 같은 중요한 정보의 생성에 적합합니다.
  • 고속성: 하드웨어 기반이므로 빠르게 난수를 생성할 수 있습니다.

2. nRF52840에서 TRNG를 활용한 난수 생성

nRF52840의 TRNG 모듈은 nRF5 SDK에서 제공하는 API를 통해 쉽게 사용할 수 있습니다. 아래는 TRNG를 활용해 난수를 생성하는 방법을 설명하는 예제 코드입니다.

2.1 TRNG 초기화 및 난수 생성 예제

#include "nrf_drv_rng.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#define RANDOM_BUFFER_SIZE 16

void rng_event_handler(uint8_t random_value)
{
    NRF_LOG_INFO("Generated random value: %d", random_value);
}

void generate_random_numbers()
{
    uint8_t random_buffer[RANDOM_BUFFER_SIZE];
    ret_code_t err_code;

    // RNG 드라이버 초기화
    err_code = nrf_drv_rng_init(NULL);
    APP_ERROR_CHECK(err_code);

    // 난수 생성
    for (int i = 0; i < RANDOM_BUFFER_SIZE; i++) {
        nrf_drv_rng_rand(&random_buffer[i], 1);
        NRF_LOG_INFO("Random byte[%d]: %02X", i, random_buffer[i]);
    }

    // RNG 종료
    nrf_drv_rng_uninit();
}

int main(void)
{
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("TRNG Example started.");
    generate_random_numbers();

    while (true)
    {
        NRF_LOG_FLUSH();
    }
}

2.2 주요 코드 설명

  1. nrf_drv_rng_init: TRNG 드라이버를 초기화합니다.
  2. nrf_drv_rng_rand: 무작위 바이트를 생성합니다.
  3. nrf_drv_rng_uninit: 작업이 완료된 후 TRNG를 비활성화합니다.

이 코드를 실행하면 콘솔에 무작위로 생성된 바이트 값이 출력됩니다.


3. 안전한 키 저장 및 관리

난수로 생성된 키는 안전하게 저장하고 관리해야만 보안성을 유지할 수 있습니다. nRF52840에서는 다음과 같은 방법으로 키를 안전하게 관리할 수 있습니다.

  1. RAM을 이용한 임시 키 저장: 재부팅 시 메모리에서 삭제되는 임시 키 저장 방법입니다.
  2. 플래시 메모리를 이용한 영구 키 저장: 재부팅 후에도 유지되는 키 저장 방법입니다.

3.1 RAM을 이용한 키 저장

RAM에 키를 저장하면 속도가 빠르지만, 재부팅 시 데이터가 사라진다는 특징이 있습니다. 다음은 RAM을 이용한 키 저장 예제입니다.

#include "nrf_crypto.h"

#define KEY_SIZE 16

void store_key_in_ram()
{
    uint8_t key[KEY_SIZE];

    // 난수를 기반으로 키 생성
    nrf_drv_rng_rand(key, KEY_SIZE);

    NRF_LOG_INFO("Generated Key:");
    for (int i = 0; i < KEY_SIZE; i++)
    {
        NRF_LOG_INFO("%02X", key[i]);
    }
}

3.2 플래시 메모리를 이용한 키 저장

플래시에 키를 저장하면 재부팅 후에도 유지되지만, 접근 시 주의가 필요합니다. nRF5 SDK에서는 Flash Data Storage(FDS) 모듈을 이용해 플래시에 데이터를 저장할 수 있습니다.

FDS를 활용한 키 저장 예제

#include "fds.h"

#define FILE_ID    0x1111
#define RECORD_KEY 0x2222
#define KEY_SIZE   16

void flash_store_key(void)
{
    uint8_t key[KEY_SIZE];
    nrf_drv_rng_rand(key, KEY_SIZE);

    fds_record_t record = {
        .file_id = FILE_ID,
        .key = RECORD_KEY,
        .data.p_data = key,
        .data.length_words = (KEY_SIZE + 3) / 4
    };

    ret_code_t err_code = fds_record_write(NULL, &record);
    APP_ERROR_CHECK(err_code);
    NRF_LOG_INFO("Key successfully stored in flash.");
}

주요 코드 설명

  1. fds_record_t: 플래시에 저장할 데이터를 정의하는 구조체입니다.
  2. fds_record_write: 데이터를 플래시에 기록하는 함수입니다.

4. 키 관리 시 보안 고려 사항

  1. 키 주기적 갱신: 장기간 동일한 키를 사용하는 것은 보안상 위험합니다.
  2. 플래시 메모리 접근 제한: 중요 데이터를 저장하는 영역에 접근 권한을 제한해야 합니다.
  3. 디버그 인터페이스 비활성화: JTAG/SWD 인터페이스를 통한 외부 접근을 차단해야 합니다.

5. 결론

nRF52840의 TRNG 모듈은 안전하고 무작위적인 난수 생성을 보장하며, 생성된 키는 RAM 또는 플래시 메모리를 통해 관리할 수 있습니다. RAM은 속도가 빠르지만 휘발성이며, 플래시는 영구성을 제공하지만 보안과 성능에 주의가 필요합니다.

안전한 키 관리를 위해서는 생성, 저장, 접근, 폐기 과정 전반에 걸쳐 보안성을 유지하는 것이 중요합니다. 이와 같은 방법을 적용함으로써 nRF52840 기반의 시스템에서 강력한 보안을 확보할 수 있습니다.

반응형