HTTP 통신

TLS Socket을 이용한 HTTPS GET, POST 통신

장병남 2023. 10. 26. 02:26

HTTP, HTTPS 스택 구조 ( https://heidyhe.github.io/https )

서버와 디바이스 통신에서 현재 가장 많이 사용되는 HTTP프로토콜은 아래와 같은 이유로 HTTP 대신 HTTPS를 주로 사용합니다.
 
- 전송 중인데 데이터는 암호화되지 않으므로 스니핑 공격에 노출됩니다.
- 중간자 공격으로 데이터가 변조될 수 있습니다.
- 웹서버가 가짜 일수도 있습니다. 
 
HTTP를 안전하게 만드는 HTTPS 솔루션은 HTTP와 TCP 사이에 SSL(Secure Sockets Layer) 또는 TLS(Transport Layer Security)로 불리는 보안 레이어를 추가하여 통신 합니다. 최근에는 SSL 보다는 TLS 용어로 많이 사용 합니다. 
 
아래 그림은 브라우저에서 HTTPS 웹사이트를 접속하는 과정입니다.

SSL handshake (simplified) ( https://heidyhe.github.io/https )

1. 브라우저는 웹 서버의 포트 443(HTTPS의 기본포트)에 대한 TCP 연결을 설정합니다.
2. 브라우저와 서버는 SSL/TLS 핸드셰이크라고 알려진  SSL/TLS 계층을 초기화합니다. 
3. 브라우저는 서버로부터 디지털 인증서를 받고 인증서에 대해 몇 가지 검사를 실행합니다. 브라우저가 인증서를 신뢰하지 않으면 경고 메시지가 표시되고 사용자가 계속 진행할지 여부를 결정할 수 있습니다.
4. 브라우저는 인증서에서 공개키를 추출한 다음 임의의 비밀키를 생성하고 공개키를 사용하여 암호화한 후 서버로 다시 보냅니다.
5. 암호화된 요청이 TCP를 통해 서버에 도착하면 서버의 SSL/TLS는 이를 해독하여 요청을 처리하는 애플리케이션 계층으로 보냅니다. HTTP 응답이 네트워크를 통해 전송되는 경우 동일한 프로세스로 진행됩니다.  
 
LTE CATM1 모뎀(이하 모뎀)을 통해 웹서버와 통신하는 방법은 위 1~5 과정에서 브라우저가 모뎀으로 대체되었다고 생각하시면 됩니다. 물론 내부적으로 약간의 차이가 있지만 정리하면 아래와 같습니다. 
 
1) 인증서를 SSL/TLS 핸드셰이크 과정에서 웹서버에서 다운로드하는 브라우저와 달리 사전에 인증서를 모뎀에 설치해야 합니다. (1~3 과정)
2) TLS 기능을 통해 TCP소켓 통신을 할 수 있도록 저장된 인증서를 불러옵니다. (4 과정)
3) HTTP 프로토콜을 사용하여 데이터를 송수신합니다. (5 과정)
 
TCP 소켓 + TLS를 합쳐서 TLS소켓이라고 표기합니다. 해당 기능을 모뎀을 사용해서 웹서버와 HTTPS통신을 1), 2), 3)의 절차로 진행하겠습니다.
 
HTTPS GET, POST를 테스트할 서버는 https://httpbin.org 입니다.

httpbin.org 웹페이지 화면 (https://httpbin.org)

먼저 모뎀에 사용할 인증서를 해당 웹페이지에서 가져옵니다. 
웹페이지 주소 왼쪽에 있는 자물쇠 아이콘을 클릭하고 '이 연결은 안전합니다'를 클릭합니다.

'인증서가 유효함'을 클릭합니다.

세부정보탭을 클릭합니다.

인증서 계층에서 httpbin.org 한 단계 위인 'Amazon RSA 2048 M02'를 클릭하고 아래 내보내기 버튼을 누릅니다.

 
이제 저장한 인증서를 모뎀 example를 사용해서 모뎀 내부에 저장하겠습니다. 
 
Arduino UNO R4(MINIMA, WIFI), NANO ESP32, NANO 33 IoT, NANO BLE Sense는 Arduino New Nano 아래에 있는 TYPE1SC_WRITE_HTTPS_CERT를 선택하시고 ESP32, RP2040의 경우 각각 아래에 있는 TYPE1SC_WRITE_HTTPS_CERT를 선택하시면 됩니다.
   
해당 example은 TYPE1SC 아두이노 라이브러리 1.0.2 버전부터 추가되었습니다.(https://github.com/codezoo-ltd/TYPE1SC) 이전 버전을 사용하시는 경우 최신버전으로 업데이트 후 사용하시기 바랍니다.

TYPE1SC_WRITE_HTTPS_CERT 선택

상단의 http_credentials.h를 선택합니다.

이전에 파일로 저장했던 인증서를 가져옵니다. 메모장을 열고 인증서를 불러옵니다. 

-----BEGIN CERTIFICAT-----
"복사해야 하는 내용"
-----END CERTIFICAT-----
 
위 "복사해야 하는 내용"을 복사해서 http_credentials.h에 붙여 넣고
줄마다 "내용\n" 형식으로 만들어 줍니다. 
아래는 새로운 인증서 내용으로 작업을 완료한 상태입니다. 
 
#ifndef HTTP_CREDENTIALS_H
#define HTTP_CREDENTIALS_H

const char serverCrt[] = "-----BEGIN CERTIFICATE-----\n"
"MIIEXjCCA0agAwIBAgITB3MSSkvL1E7HtTvq8ZSELToPoTANBgkqhkiG9w0BAQsF\n"
"ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n"
"b24gUm9vdCBDQSAxMB4XDTIyMDgyMzIyMjUzMFoXDTMwMDgyMzIyMjUzMFowPDEL\n"
"MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEcMBoGA1UEAxMTQW1hem9uIFJT\n"
"QSAyMDQ4IE0wMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALtDGMZa\n"
"qHneKei1by6+pUPPLljTB143Si6VpEWPc6mSkFhZb/6qrkZyoHlQLbDYnI2D7hD0\n"
"sdzEqfnuAjIsuXQLG3A8TvX6V3oFNBFVe8NlLJHvBseKY88saLwufxkZVwk74g4n\n"
"WlNMXzla9Y5F3wwRHwMVH443xGz6UtGSZSqQ94eFx5X7Tlqt8whi8qCaKdZ5rNak\n"
"+r9nUThOeClqFd4oXych//Rc7Y0eX1KNWHYSI1Nk31mYgiK3JvH063g+K9tHA63Z\n"
"eTgKgndlh+WI+zv7i44HepRZjA1FYwYZ9Vv/9UkC5Yz8/yU65fgjaE+wVHM4e/Yy\n"
"C2osrPWE7gJ+dXMCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD\n"
"VR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNV\n"
"HQ4EFgQUwDFSzVpQw4J8dHHOy+mc+XrrguIwHwYDVR0jBBgwFoAUhBjMhTTsvAyU\n"
"lC4IWZzHshBOCggwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8v\n"
"b2NzcC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDov\n"
"L2NydC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8E\n"
"ODA2MDSgMqAwhi5odHRwOi8vY3JsLnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jv\n"
"b3RjYTEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IB\n"
"AQAtTi6Fs0Azfi+iwm7jrz+CSxHH+uHl7Law3MQSXVtR8RV53PtR6r/6gNpqlzdo\n"
"Zq4FKbADi1v9Bun8RY8D51uedRfjsbeodizeBB8nXmeyD33Ep7VATj4ozcd31YFV\n"
"fgRhvTSxNrrTlNpWkUk0m3BMPv8sg381HhA6uEYokE5q9uws/3YkKqRiEz3TsaWm\n"
"JqIRZhMbgAfp7O7FUwFIb7UIspogZSKxPIWJpxiPo3TcBambbVtQOcNRWz5qCQdD\n"
"slI2yayq0n2TXoHyNCLEH8rpsJRVILFsg0jc7BaFrMnF462+ajSehgj12IidNeRN\n"
"4zl+EoNaWdpnWndvSpAEkq2P\n"
"-----END CERTIFICATE-----";

#endif
 
이제 저장 후 보드를 연결하고 업로드해서 인증서를 모뎀에 등록합니다.
인증서는 모뎀 2번 슬롯에 저장했습니다. #define PROFILE_ID 2

인증서 등록

이제 등록한 인증서를 이용해서 웹서버에 HTTPS GET 테스트를 하겠습니다. 
TYPE1SC_TLS_Socket_HTTPS_GET example를 실행합니다. 

 
httpbin.org 서버의 HTTPS 기본포트(443)에 접속하도록 주소가 지정되어 있습니다. 다른 서버에 접속하실 경우 해당 정보를 수정하시면 됩니다.

HTTPS GET명령은 https://httpbin.org/get 주소에 아래와 보냈습니다. 
GET /get HTTP/1.1
Host: httpbin.org
 
코드로 구현한 부분은 아래와 같습니다. String으로 구문을 작성 후 TCP 소켓을 통해 보내고 응답을 받습니다.

실행한 결과입니다.

ESP32 IoT 보드로 TLS Socket HTTPS GET을 실행한 영상입니다.
통신결과를 OLED에 한 줄씩 출력하기 때문에 실제 통신시간 보다 화면 표시에 걸리는 시간이 좀 더 걸립니다. 참고하셔서 실제 통신을 구현하실 경우 OLED에는 결과만 표시하도록 구현하시기 바랍니다. 

 
웹서버에 HTTPS POST 테스트를 하겠습니다. 
TYPE1SC_TLS_Socket_HTTPS_POST example를 실행합니다. 

예제코드에서 주의 깊게 봐야 할 내용은 아래 74번 라인부터입니다. 
 https://httpbin.org/post 주소에 email과 password를 json 형식으로 POST 합니다. 
json형식으로 보내는 데이터는 형식을 지정 후 마지막에 기록합니다. 

실행한 결과입니다.
모뎀에서 전송한 json타입의 email, password 데이터가 서버에서 정상수신(200) 되었고, 
수신결과를 확인해 보면  "data" 항목에는 모뎀에서의 전송한 데이터를 확인할 수 있고,
"json"항목에는 email과 password 항목에 각각 적용된 것을 확인할 수 있습니다. 
 
실제 구현시 서버 개발자와 데이터를 어떤 식으로 보내고 받는지 정의하신 후 그 형식에 맞춰서 펌웨어에서 구문을 만들어서 보내고 서버 응답값을 통해  제대로 적용되었는지 확인하시면 통신의 신뢰성을 확보하실 수 있습니다. 

Arduino UNO R4 WIFI보드로 TLS Socket HTTPS POST를 실행한 영상입니다. 

 
Murata Type1SC 모듈 구매, 자료 관련 문의
(주)아성코리아
전지만 이사 010-5418-8812 mlcc@asung.com
박상인 수석 010-6556-5405 sipark@asung.com

LTE-CATM1 내장형 모뎀 대량 구매 상담, 외주 개발, 협업 문의
(주)코드주
장병남 대표 010-8965-1323 rooney.jang@codezoo.co.kr
 
https://www.devicemart.co.kr/goods/view?no=14077527

 

LTE-CatM1 내장형 모뎀 / 사물인터넷 통신모듈

사물인터넷 개발을 위한 LTE 모듈입니다. / CodeZoo / 사물인터넷 통신모듈 / 유심은 상품상세의 링크에서 별도 구매가 필요합니다.

www.devicemart.co.kr

https://smartstore.naver.com/codezoo/products/7153689192

 

Vodafone Global IoT SIM Card : codezoo

[codezoo] IoT Global SIM, IoT Connectivity, IoT Device

smartstore.naver.com