ESP32와 서버 간 안전한 통신 구축 (TLS/SSL 활용)
ESP32는 사물인터넷(IoT) 기기에서 널리 사용되는 저전력 마이크로컨트롤러로, 인터넷을 통한 데이터 송수신이 필수적입니다. 그러나 네트워크 환경에서는 보안이 중요한 요소이며, 특히 기기와 서버 간의 통신이 보호되지 않으면 악의적인 공격에 취약할 수 있습니다. 이에 따라 ESP32에서는 TLS/SSL을 활용하여 보안 통신을 구축하는 방법을 제공합니다.
본 포스팅에서는 ESP32와 서버 간의 TLS/SSL 기반 안전한 통신을 구축하는 방법을 설명하고, 실제로 ESP-IDF 환경에서 구현할 수 있도록 예제 코드를 포함하여 소개하겠습니다.
1. TLS/SSL 개요
TLS(Transport Layer Security) 및 SSL(Secure Sockets Layer)은 인터넷을 통한 데이터 송수신을 보호하는 암호화 프로토콜입니다. SSL은 초기 버전이며 현재는 보안상의 이유로 더 이상 사용되지 않고, 대신 TLS가 표준으로 자리 잡았습니다. ESP32는 mbedTLS를 활용하여 TLS 통신을 지원합니다.
TLS를 사용하면 다음과 같은 보안 기능을 제공할 수 있습니다:
- 데이터 암호화: 송수신되는 데이터를 암호화하여 외부에서 내용을 확인할 수 없도록 합니다.
- 데이터 무결성 보호: 전송 중 데이터가 변조되지 않았음을 보장합니다.
- 서버 인증: 클라이언트가 신뢰할 수 있는 서버와 통신하고 있음을 확인합니다.
- 클라이언트 인증(선택 사항): 서버가 특정 클라이언트만 접근할 수 있도록 인증할 수 있습니다.
2. ESP32에서 TLS/SSL 적용 방법
ESP-IDF에서는 esp_tls
API를 사용하여 TLS를 통한 보안 통신을 쉽게 구축할 수 있습니다. HTTPS를 활용하는 경우 esp_http_client
를 사용할 수도 있으며, MQTT와 같은 프로토콜에서도 TLS 기반 보안 연결이 가능합니다.
2.1 사전 준비
ESP32에서 TLS/SSL을 사용하기 위해서는 신뢰할 수 있는 인증서(Certificate)가 필요합니다. 기본적으로 다음 세 가지 인증서가 사용됩니다:
- 서버 인증서(Server Certificate): 서버의 신원을 인증합니다.
- 클라이언트 인증서(Client Certificate, 선택 사항): 클라이언트가 서버에 인증될 때 사용됩니다.
- CA 인증서(CA Certificate): 서버 인증서가 신뢰할 수 있는 기관에 의해 발급되었음을 확인하는 데 사용됩니다.
인증서는 PEM 또는 DER 형식으로 제공될 수 있으며, ESP32에서는 주로 PEM 형식을 사용합니다.
3. ESP32에서 TLS를 활용한 HTTPS 요청 예제
ESP-IDF의 esp_http_client
를 사용하여 HTTPS 요청을 보내는 예제를 작성하겠습니다. 여기에서는 Let’s Encrypt에서 발급된 서버 인증서를 사용하는 HTTPS 서버에 요청하는 예제입니다.
3.1 필요한 인증서 준비
서버의 CA 인증서를 가져와 cert.pem
파일로 저장합니다. 인증서는 아래 명령어를 사용하여 가져올 수 있습니다:
openssl s_client -showcerts -connect example.com:443 </dev/null 2>/dev/null | openssl x509 -outform PEM > cert.pem
이제 cert.pem
파일의 내용을 ESP32 코드에 포함시킵니다.
3.2 HTTPS 요청 코드 작성
아래는 esp_http_client
를 활용하여 TLS 기반 HTTPS 요청을 수행하는 코드입니다.
#include <stdio.h>
#include "esp_log.h"
#include "esp_err.h"
#include "esp_http_client.h"
static const char *TAG = "HTTPS_CLIENT";
// CA 인증서 (PEM 형식으로 저장된 문자열)
extern const char ca_cert_pem_start[] asm("_binary_cert_pem_start");
extern const char ca_cert_pem_end[] asm("_binary_cert_pem_end");
esp_err_t _http_event_handler(esp_http_client_event_t *evt) {
switch (evt->event_id) {
case HTTP_EVENT_ERROR:
ESP_LOGI(TAG, "HTTP_EVENT_ERROR");
break;
case HTTP_EVENT_ON_CONNECTED:
ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED");
break;
case HTTP_EVENT_HEADER_SENT:
ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT");
break;
case HTTP_EVENT_ON_HEADER:
ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
break;
case HTTP_EVENT_ON_DATA:
ESP_LOGI(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
break;
case HTTP_EVENT_ON_FINISH:
ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH");
break;
case HTTP_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
break;
}
return ESP_OK;
}
void https_request() {
esp_http_client_config_t config = {
.url = "https://example.com/api/data",
.cert_pem = ca_cert_pem_start,
.event_handler = _http_event_handler,
};
esp_http_client_handle_t client = esp_http_client_init(&config);
esp_http_client_perform(client);
esp_http_client_cleanup(client);
}
void app_main() {
ESP_LOGI(TAG, "Starting HTTPS Request");
https_request();
}
3.3 코드 설명
esp_http_client_config_t
구조체에서url
과cert_pem
을 설정하여 HTTPS 요청을 보냅니다.esp_http_client_perform()
함수를 호출하면 요청이 실행되며, 응답을 받을 수 있습니다.esp_http_client_cleanup()
으로 클라이언트를 정리합니다.
4. 결론
본 포스팅에서는 ESP32와 서버 간 안전한 TLS/SSL 기반 통신 구축 방법을 살펴보았습니다. TLS를 활용하면 데이터의 보안성을 강화할 수 있으며, 이를 통해 악의적인 공격으로부터 보호할 수 있습니다.
ESP-IDF에서는 esp_tls
및 esp_http_client
API를 활용하여 간단하게 TLS를 적용할 수 있으며, 필요에 따라 MQTT 및 WebSocket에도 적용할 수 있습니다. 실전 개발 환경에서 TLS를 적용하여 보안을 강화하시기를 권장드립니다.
'ESP32 IDF' 카테고리의 다른 글
ESP32 암호화 모듈의 장단점 정리 (0) | 2025.02.28 |
---|---|
ESP32 IDF 암호화 성능 최적화 방법 (0) | 2025.02.28 |
ESP32 IDF 펌웨어 무결성을 보호하는 방법 (0) | 2025.02.28 |
ESP32 ECDSA를 이용한 서명 생성과 검증 (0) | 2025.02.28 |
ESP32 난수 생성과 시드(seed) 관리 방법 (0) | 2025.02.28 |