پیش فرض برای ایجاد یک پروتکل ارتباطی امن در C

قبل از غواصی در پیاده سازی، محیط توسعه خود را شامل کامپایلر C (GCC یا Clang)، دانش پایه برنامه نویسی سوکت، و کتابخانه OpenSSL نصب شده است. OpenSSL ارائه می دهد پیاده سازی قوی از الگوریتم های رمزنگاری، و آن را انتخاب استاندارد برای ارتباطات امن در C. Onserver، نصب OpenSSL از طریق مدیر بسته خود (به عنوان مثال، [F:0، استفاده از پیش از ویندوز، یا با منبع آشنا و یا سازنده از منبع آگاه از پیش فرض می شود.

درک بلوک های ساختمان رمزنگاری

یک پروتکل ارتباطی امن در سه ستون قرار دارد: محرمانه بودن، صداقت و تأیید اعتبار. Confidentiality از طریق رمزگذاری به دست می آید، اطمینان حاصل می کند که تنها گیرنده در نظر گرفته شده می تواند پیام را بخواند. یکپارچگی تضمین می کند که داده ها در حمل و نقل تغییر نکرده اند و هویت احزاب برقراری ارتباط را در یک پروتکل سفارشی، شما به طور معمول رمزگذاری نامتقارن را ترکیب می کنید، هش کردن با کد های تأیید هویت (H) و مکانیسم تبادل کلید - مانند مکانیسم تبادل کلید - او.

رمزگذاری متقارن با AES

استاندارد رمزگذاری پیشرفته (AES) به طور گسترده ای مورد استفاده قرار می گیرد، آن را در بلوک های 128 بیتی عمل می کند و از اندازه های کلیدی 128، 192 یا 256 بیت برای ارتباطات امن پشتیبانی می کند، AES را در حالت Galois /Counter (GCM)، که هر دو محرمانه بودن و یکپارچگی در یک عملیات واحد را فراهم می کند. OpenSSL رابط EVP رمزگذاری آن را به طور مستقیم و با اطمینان از داده های قدیمی تر ترکیب می کند.

کلید تبادل با Diffie - Hellman

برای توافق ایمن در مورد یک راز مشترک در مورد کانال ناامن، استفاده از Diffie-Hellman (DH) تبادل کلید خصوصی و تبادل پارامترهای عمومی، پس از آن محاسبه یک راز مشترک (FLT:0Diffie - Hellman [FLT 1] آسیب پذیر است به حملات انسان-در برابر اگر شما معتبر نیست، پس از آن ممکن است به کار گرفته شده است برای گسترش امضاهای الکترونیکی.

پیام صداقت و اعتبار با HMAC

برای تأیید اینکه یک پیام با دستکاری نشده است، یک کد تأیید اعتبار پیام مبتنی بر هش (HMAC) را به هر رمز رمز شده hhosttext اضافه کنید. HMAC از یک کلید مخفی مشترک و یک تابع هش رمزنگاری شده (به عنوان مثال، SHA-256) استفاده می کند. گیرنده HMAC را در داده های دریافت شده بازنویسی می کند و آن را با ارزش انتقال شده مقایسه می کند.

گزینه Up OpenSSL در پروژه C شما

OpenSSL نیاز به اولیه دقیق دارد و شامل هدرهای لازم و فراخوانی (FLT:1) و در ابتدای برنامه شما می شود.

#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 Socket Layer

در این صورت، در صورت لزوم، به صورت زیر به صورت زیر به صورت زیر به شما می رسد و به صورت مستقیم به آن اشاره می کند.

مثال های سروری 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 Key Exchange

پس از ایجاد اتصال TCP، مشتری و سرور یک تبادل کلید DH را انجام می دهند. [۵] هر طرف یک جفت کلید DH با استفاده از OpenSSL (FLT:15 API) ایجاد می کند. کلید عمومی بر روی سوکت ارسال می شود و هر دو طرف یک راز مشترک را با استفاده از FLT ۱۶:۱۶ برای سادگی، استفاده از یک گروه اول ثابت (e.g.f:17) ، [F]

// 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);

در پایان دریافت، همتا کلید عمومی را با استفاده از وارد می کند و سپس راز مشترک را به دست می آورد. راز مشتق شده می تواند حک شده (به عنوان مثال، با SHA-256) برای تولید یک کلید یکنواخت برای AES و HMAC.

رمزگذاری و رمزگشایی پیام ها با AES-GCM

AES-GCM حالت ترجیحی است زیرا هر دو رمزگذاری و یک برچسب تأییدیه را در یک عملیات فراهم می کند.استفاده از OpenSSL (FLT:21) با ، شما نیاز به یک شماره 12 به یک (IV) و کلید 256 بیتی که از راز مشترک گرفته شده است. [دستورال] رمز و رمز ارسال است.

// 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 (یا Leveraging GCM Tag)

اگر تصمیم به استفاده از AES-GCM ندارید، می توانید با AES-CBC رمزنگاری کنید و سپس HMAC را بر روی رمز استفاده کنید. از OpenSSL با SHA-256] برای حذف HMACCM پس از کلید Hciphertext، گیرنده محاسبه و مقایسه رویکرد نیاز به دو کلید دارد: یکی برای رمزگذاری، برای یک عامل مخفی (MAC) مانند HDF.

قرار دادن آن با هم: گردش کار کامل

  1. یک اتصال TCP بین مشتری و سرور ایجاد کنید.
  2. هر دو طرف جفت های کلیدی ephemeral Diffie-Hellman را تولید می کنند.
  3. کلید های عمومی را مبادله کنید و راز مشترک را محاسبه کنید.
  4. کلید AES 256 بیتی و یک کلید HMAC 256 بیتی (یا از همان کلید برای GCM استفاده کنید)
  5. مشتری یک Nonce (۱۲ بایت تصادفی) را ارسال می کند و سپس پیام رمزگذاری شده AES-GCM به علاوه برچسب. Server decrypts و اعتبارسنجی.
  6. سرور یک پاسخ با استفاده از یک نونس جدید ارسال می کند (هرگز بدون هیچ گونه وقفه ای را با همان کلید استفاده نمی کند).
  7. هر دو طرف می توانند پیام های تبادلی را ادامه دهند؛ برای جلسات طولانی، به طور دوره ای با استفاده از همان DH دست دادن یا مکانیسم تکراری.

بهترین روش های امنیتی

  • از ژنراتورهای عددی قوی استفاده کنید.[۱۰] تماس بگیرید [FLT۲۶] از OpenSSL برای تولید کلید، nonces و کلیدهای خصوصی DH استفاده کنید.
  • تمام داده های دریافت شده را تأیید کنید.[۱۰] طول، پارامترهای کلید عمومی (به عنوان مثال، اطمینان حاصل کنید که p نخست است، g یک ژنراتور است و تگ های HMAC قبل از پردازش.
  • کلید های سخت یا پیش فرض های سخت را همیشه در هر جلسه برای ارائه راز کامل پیش رو مذاکره کنید.
  • (اگر این کار را انجام می دهد، به درستی انجام می دهد و یا به صورت مستقیم به آن اشاره می کند و به آن اشاره می کند که چرا این کار را انجام می دهد.
  • وابستگی ها را به روز نگه دارید.[۱۰] به طور منظم OpenSSL را به روز رسانی کنید تا آسیب پذیری های شناخته شده را وصل کنید.
  • استفاده از TLS به جای یک پروتکل سفارشی برای سیستم های تولیدی، تکیه بر پروتکل های به خوبی تست شده مانند TLS 1.3، ساخت یک پروتکل سفارشی از ابتدا، اثبات خطا و توصیه نمی شود مگر اینکه شما تخصص رمزنگاری عمیق داشته باشید.

تست پروتکل

پیاده سازی خود را با اجرای مشتری و سرور در همان ماشین (محلی) تست کنید و تأیید کنید که پیام ها به درستی رمزگشایی می شوند. خطاهایی مانند رمزسازی دستکاری شده یا عدم اعتبار را برای اطمینان از اینکه پروتکل آنها را رد می کند، استفاده از ابزارهایی مانند Wireshark برای بازرسی ترافیک شبکه خام و تأیید اینکه متن ساده قابل مشاهده نیست.

نتیجه گیری

ساخت یک پروتکل ارتباطی امن در C یک تمرین یادگیری عالی است، اما نیاز به توجه دقیق به جزئیات دارد.با استفاده از پیاده سازی های اثبات شده OpenSSL از Diffie-Hellman، AES-GCM، و HMAC، شما می توانید یک سیستم را ایجاد کنید که محرمانه بودن، یکپارچگی و تأیید همیشه از بهترین شیوه های رمزنگاری پیروی می کند: استفاده از کلید های جدی، و با استفاده از یک فرآیند یادگیری دقیق، بدون اطمینان از داده ها، همه چیز را در نظر می گیرد.