C의 보안 통신 프로토콜 구축에 대한 필수 사항

구현하기 전에 개발 환경을 유지하십시오. C 컴파일러 (GCC 또는 Clang), 소켓 프로그래밍의 기본 지식 및 OpenSSL 라이브러리가 설치되어 있습니다. OpenSSL은 C. On Linux에서 보안 통신을 위한 표준 선택을 만들고, 패키지 관리자 (예를 들어, )를 통해 OpenSSL을 설치합니다. Windows에서 소스에서 사전 컴파일 된 바이너리 또는 빌드를 사용합니다. Familiity / TCP / 서버는 클라이언트와 함께 클라이언트 모델을 가정합니다.

Cryptographic Building Blocks에 대한 이해

보안 통신 프로토콜은 세 가지 기둥에 휴식 : 기밀성, 무결성 및 인증. 기밀성은 암호화를 통해 달성되며 의도 된 수신자는 메시지를 읽을 수 있습니다. Integrity는 데이터가 transit에서 변경되지 않았음을 보장합니다. 인증은 식별 당사자의 식별을 검증합니다. 사용자 정의 프로토콜에서 일반적으로 비대칭 암호화를 결합하여 메시지 인증 코드 (HMAC) 및 Diffell-Hiffell-Hiffman과 같은 주요 교환 메커니즘을 해시합니다.

AES와 Symmetric Encryption

고급 암호화 표준 (AES)는 가장 널리 사용되는 비대칭 암호화입니다. 그것은 128 비트 블록에서 작동하고 128, 192, 또는 256 비트의 주요 크기를 지원합니다. 안전한 통신을 위해, AES를 Galois /Counter 모드 (GCM)에서 선호합니다. 단일 작업에서 기밀성과 무결성을 모두 제공하는. OpenSSL의 EVP 인터페이스는 AES-GCM과 암호화 데이터를 바로 만듭니다. ECBC와 CBC 인증과 같은 오래된 모드를 피하십시오.

Diffie–Hellman과의 주요 교환

이 웹 사이트는 귀하가 웹 사이트를 탐색하는 동안 귀하의 경험을 향상시키기 위해 쿠키를 사용합니다. 이 쿠키들 중에서 필요에 따라 분류 된 쿠키는 웹 사이트의 기본적인 기능을 수행하는 데 필수적이므로 브라우저에 저장됩니다. 또한이 웹 사이트의 사용 방식을 분석하고 이해하는 데 도움이되는 제 3 자 쿠키를 사용합니다. 이 쿠키는 귀하의 동의하에 만 브라우저에 저장됩니다. 이러한 쿠키를 거부 할 수도 있습니다. 이러한 쿠키 중 일부를 선택 해제하면 검색 환경에 영향을 미칠 수 있습니다.

HMAC와 메시지 통합 및 인증

HMAC는 암호화된 암호화된 암호화된 암호화된 암호화된 암호화된 암호화된 암호화된 암호화된 암호화된 암호화된 암호화된 메시지 인증 코드(HMAC)를 추가하여 메시지가 사라지지 않도록 합니다. HMAC는 공유된 비밀 키와 암호화 해시 함수(예: SHA‐256)을 사용합니다. 수신된 데이터에 HMAC를 재조합하고 전송된 값에 비교합니다. 이 단계는 재생과 타당성 공격을 방지합니다. 또는, AES-G는 동일한 프로토콜을 포함하는 프로토콜을 포함합니다.

C Project에서 OpenSSL 설정

OpenSSL은 주의적인 초기화가 필요합니다. 필요한 헤더와 호출 과 ]]을 프로그램 시작시 포함하십시오. 오류 처리의 경우 과 ]를 사용하십시오. 연결하면 를 컴파일러 플래그에 추가하십시오. 최소 설정은 다음과 같습니다.

#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/err.h>
// Initialize OpenSSL
void init_openssl() {
 SSL_load_error_strings();
 OpenSSL_add_all_algorithms();
}

TCP 소켓 층을 건축

프로토콜의 밑으로는 TCP가 될 것입니다. 신뢰할 수있는, 주문 된 배달을 제공합니다. 수신 연결과 손을 시작시키는 클라이언트를 듣는 서버를 만듭니다. , ], , , ], , 클라이언트 측에 ]를 사용하여 클라이언트의 오류를 처리하십시오. 파일 및 우아한 사용 후 오류가 발생하면 오류가 발생하지 않습니다.

서버 예제 Skeleton

int server_fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);
bind(server_fd, (struct sockaddr*)&address, sizeof(address));
listen(server_fd, 3);
int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &addr_len);

클라이언트 예제 Skeleton

int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));

Diffie–Hellman 키 교환 구현

TCP 연결을 설정한 후 클라이언트와 서버는 DH 키 교환을 수행합니다. 각 측면은 OpenSSL의 API를 사용하여 DH 키 쌍을 생성합니다. 공개 키는 소켓을 통해 전송되며, 양쪽 모두는 공유 비밀을 사용하여 를 derive합니다. 단순성을 위해, 고정된 프라임 그룹을 사용합니다 (예를들면 에서 매개변수를 가진 ). 실제 프로토콜을 사용하거나, 먼저 그룹을 사용할 수 있습니다.

// Generate DH parameters
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
EVP_PKEY_paramgen_init(pctx);
EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, 2048);
EVP_PKEY *params = NULL;
EVP_PKEY_paramgen(pctx, &params);

// Generate key pair
EVP_PKEY_CTX *kctx = EVP_PKEY_CTX_new(params, NULL);
EVP_PKEY_keygen_init(kctx);
EVP_PKEY *my_key = NULL;
EVP_PKEY_keygen(kctx, &my_key);

// Export public key to send
unsigned char *pub_key_der = NULL;
int pub_len = i2d_PUBKEY(my_key, &pub_key_der);
send(sock, pub_key_der, pub_len, 0);

수신 끝에, 피어는 ]을 사용하여 공공 키를 가져와 공유 비밀을 파생합니다. 파생 된 비밀은 AES 및 HMAC에 대한 균일 한 키를 생성하기 위해 (예 : SHA‐256)을 해시 할 수 있습니다.

AES‐GCM과 메시지 암호화

AES-GCM은 암호화와 인증 태그를 하나의 작업으로 제공하기 때문에 선호하는 모드입니다. OpenSSL의 를 로 사용하십시오. 12-byte nonce (IV)와 DH 공유 비밀에서 파생 된 256-bit 키가 필요합니다. ciphertext는 펑크에서 생성되며 최종 업데이트 후 16-byte 태그를 검색합니다. 비례, ciphertext, crypted 태그를 보내면 인증 태그가 사라집니다. [FLT : 23] 태그가 함께 설정되면 인증 태그가 사라집니다. [FLT : 23] 태그가 함께 설정되면 인증 태그가 사라집니다.

// Encryption
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, key, nonce);
unsigned char ciphertext[1024];
int outlen;
EVP_EncryptUpdate(ctx, ciphertext, &outlen, plaintext, len);
int tmplen;
EVP_EncryptFinal_ex(ctx, ciphertext + outlen, &tmplen);
unsigned char tag[16];
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag);

HMAC(또는 GCM Tag를 활용)로 Integrity 추가

AES-GCM을 사용하지 않는 경우 AES-CBC로 암호화하고 그 후 ciphertext에 HMAC를 컴파일 할 수 있습니다. OpenSSL에서 SHA‐256을 사용하여 를 사용하십시오. ciphertext 후 HMAC를 승인하십시오. 수신기는 재 계산 및 비교합니다. 이 접근법은 두 가지 키가 필요합니다. 암호화를위한 하나, HMAC에 대한 하나. 공유 비밀에서 모두 키 (MAC)를 사용하여 중요한 ‐GFCM을 감소시킵니다. 그러나 HMAC는 복잡한 기능을 제거해야합니다. 그러나 HMAC는 HMAC (F).

그것을 함께 넣어 : 완전한 Workflow

  1. 클라이언트와 서버 간의 TCP 연결을 설정한다.
  2. 양쪽 모두 ephemeral Diffie-Hellman 키 쌍을 생성합니다.
  3. 공용 키 교환 및 공유 비밀을 준수합니다.
  4. 256비트 AES 키와 256비트 HMAC 키(또는 GCM의 동일한 키를 사용합니다)를 사용하세요.
  5. 클라이언트는 비례 (12 바이트 임의)를 보내고 AES ‐ GCM 암호화 된 메시지 플러스 태그. 서버는 해독하고 검증합니다.
  6. Server는 새로운 비례를 사용하여 응답을 보냅니다 (같은 열쇠를 가진 아무런 재사용하지 않습니다).
  7. 양쪽 모두는 메시지를 바꾸는 것을 계속할 수 있습니다; 긴 회의를 위해, 동일한 DH handhake 또는 ratchet 기계장치를 사용하여 재키 정기적으로.

보안 모범 사례

  • 강력한 임의 번호 생성기를 사용합니다. [[FLT::26]]]] OpenSSL에서 키, 정오 및 DH 개인 키를 생성합니다. 또는 ]를 암호화 목적으로 사용하지 마십시오.
  • Validate는 모든 수신된 데이터를 수신합니다.] 체크 길이, 공공 키 매개 변수 (예를 들어, p은 프라임, g는 생성기), 처리하기 전에 HMAC 태그입니다.
  • Avoid 하드코딩 키 또는 기본값. 항상 세션 당 키를 신선한 협상하여 완벽한 전달을 제공합니다.
  • Handle errors gracefully. 디코딩이 실패하거나 HMAC 검증이 실패하면 연결이 닫고 이벤트를 로그합니다. 실패가 발생했는지 알 수 없습니다.
  • Keep Dependencies update. 정규 업데이트 OpenSSL to patch known vulnerabilities. OpenSSL documentation]]는 deprecation과 모범 사례에 대한 지도를 제공합니다.
  • 사용자 지정 프로토콜보다 TLS를 사용하는 것이 좋습니다.] 생산 시스템의 경우 TLS 1.3과 같은 잘 테스트 된 프로토콜에 의존합니다. 스크래치에서 사용자 정의 프로토콜을 구축하면 스크래치가 오류 프로앤드가 아니라 심 암호화 전문성이 없는 것이 좋습니다.

프로토콜 테스트

클라이언트와 서버가 동일한 기계 (localhost)에 실행하여 구현을 테스트하고 메시지가 올바르게 해독하는 것을 확인합니다. tampered ciphertext 또는 잘못된 nonces와 같은 오류를 도입하여 프로토콜이 거부되도록합니다. Wireshark와 같은 도구를 사용하여 원시 네트워크 트래픽을 검사하고 일반 텍스트가 보이지 않습니다. 단자 테스트를 위해 소켓 층을 시뮬레이션하고 암호화 원시를 테스트하십시오. OpenSSL의 디버깅은 중간값을 검증할 수 있습니다.

관련 기사

C의 안전한 통신 프로토콜을 구축하는 것은 훌륭한 학습 운동이지만 세부 사항에 대한 매우주의가 필요합니다. OpenSSL의 Diffie‐Hellman, AES‐GCM 및 HMAC의 입증 된 구현을 활용하여 기밀성, 무결성 및 인증을 제공하는 시스템을 만들 수 있습니다. 항상 암호화 모범 사례를 따르십시오. 강력한 임의성을 사용하여 KDF를 가진 파생 세션 키는 결코 아무런 의존을 재사용하지 않으며 모든 데이터를 완전히 검증하지 않습니다. 모든 위협을 위해 [LT]는 다음과 같은 표준 프로토콜을 고려하고 있습니다. [LT] [LT] [LT]]