Prerequisites for Building a Secure Communications Protocol in C

לפני צלילה ליישום, להבטיח סביבת הפיתוח שלך כולל C מהפך (GCC או Clang), ידע בסיסי של תכנות שקע, ואת ספריית OpenSSL מותקן. OpenSSL מספק יישום חזק של אלגוריתמים קריפטוגרפיים, מה שהופך אותו הבחירה הסטנדרטית לתקשורת מאובטחת ב- C. On Linux, להתקין את OpenSSL באמצעות מנהל החבילה שלך (למשל, FLT:0) ב-Windows, שימוש טרום-comedern עם קוד פתוח / CPS הנחה עם ® או קוד פתוח עם .

הבנת בלוקי בניין Cryptographic

פרוטוקול תקשורת מאובטח נח על שלושה עמודי עמוד: סודיות, יושרה ואימות.קונדינטיות מושגת באמצעות הצפנה, ומבטיח שרק הנמען המיועד יכול לקרוא את ההודעה.אינטגרity מבטיחה כי הנתונים לא השתנו במעבר. Authentication מאמתים את זהויות של מפלגות התקשורת.בפרוטוקול מותאם אישית, בדרך כלל משלב הצפנה סימטרית, החלת עם אימות הודעות (HC), ו- Diffie-החלפת מנגנון כגון .

הצפנה סימפונית עם AES

תקן הצפנה מתקדם (AES) הוא ה- סימטרי הנפוץ ביותר cipher.It פועל על 128-bit בלוקים ותומך בגדלים מרכזיים של 128, 192, או 256 ביטים.עבור תקשורת בטוחה, מעדיף AES ב- Galois/Counter Mode (GCM), המספק סודיות ושלמות במבצע יחיד.OpenSSL's EVP עושה את זה פשוט להצפין ולפענחמה עם נתונים עם AG-CM או למנוע מ-ACM.

החלפה עם דיפי-הלמן

כדי להסכים באופן מאובטח על סוד משותף על ערוץ לא מאובטח, השתמש ב- Diffie-Hellman (DH) חילופי מפתח.שני הצדדים מייצרים מפתחות פרטיים והחלפת פרמטרים ציבוריים, ולאחר מכן למקם סוד משותף.

הודעה אינטגרטיבית ואותנטיות עם HMAC

כדי לאמת כי הודעה לא נצפתה עם, נספח קוד ההודעה מבוסס האשרה (HMAC) לכל קידוד מוצפן מוצפן. HMAC משתמש מפתח סודי משותף ותפקוד hash הצפנה (למשל, SHA-256) למקלט מאמת את ה-HMAC על הנתונים שהתקבלו ומשווה אותו לערך המועבר.

הקמת OpenSSL בפרויקט C שלך

פתחה דורש כפלה זהירה.מכיל את ראשי התיבות הדרושים וקוראים (FLT:1 ו-) בתחילת התוכנית שלך.עבור טיפול שגיאה, להשתמש ב-FLT:3 ו-FLT:4 כאשר קישור, להוסיף 5 לדגלים שלך.

#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

(ה) ,התחבורה הבסיסית לפרוטוקול שלך תהיה TCP, אשר מספקת אספקה אמינה, מסודרת, צור שרת שמקשיב לחיבורים נכנסים ללקוח אשר יוזם את לחיצת היד, השתמש במכשולים סטנדרטיים של POSIX עם FLT 7, ⁇ 8, FLT:9, FLT:9 בצד, ו-FLT:11,LT 11, LTF בצד השני כדי לטפל בשגיאות קרוב ל-:12 ו- 12.

דוגמא: 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'sFLT:15 API.המפתח הציבורי נשלח מעל השקע, ושני הצדדים שואבים סוד משותף באמצעות FLT:16 פשטות, השתמש בקבוצה ראשונית קבועה (למשל, 17 LT עם פרמטרים מ-F:18 בפרוטוקול אמיתי, או מוגדר מראש, השתמש בפרמטרים מראש או ניהול משא ומתן מראש).

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

בסוף הקבלה, העמית מייבב את המפתח הציבורי באמצעות FLT:20 ואז שואב את הסוד המשותף.הסוד הנקוב יכול להיות מודבק (למשל, עם SHA-256) כדי לייצר מפתח אחיד עבור AES ו- HMAC.

קידוד והודעות קידוד עם AES-GCM

(א) הוא המצב המועדף משום שהוא מספק גם הצפנה וגם תג אימות בפעולה אחת. השתמש ב- OpenSSL'sFLT:21 עם FLT:22 (אתה צריך צומת 12-על-ידי (IV) ואת אימות מפתח 256 סיביות הנגזר מן ה- DH משותף , phertext מיוצר ב- סדקים, ולאחר העדכון הסופי, אתה משחזר את תג ה-byte, ללא קידוד, ו-Fact, קובץ ה-S.

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

הוספת אינטגרity עם HMAC (או Leveraging GCM Tag)

אם תבחר לא להשתמש ב-AES-GCM, תוכל להצפין עם AESCBC ולאחר מכן למקם HMAC על ה- ciphertext. UseFLT:25 מ-OpenSSL עם SHA-256. Append the HMAC לאחר ה- cipherates והשוואה.com זו דורשת שני מפתחות: אחד עבור הצפנה, אחד עבור HMAC משותף, כמו הפונקציה ACMMAC.

לשים את זה ביחד: זרימה שלמה

  1. יצירת קשר TCP בין הלקוח לשרת.
  2. שני הצדדים מייצרים זוגות מפתח אפסיים של דיפי-הלמן.
  3. להחליף מפתחות ציבוריים ולעצב את הסוד המשותף.
  4. דרבי מפתח 256 סיביות AES ומפתח HMAC של 256 סיביות (או להשתמש באותו מפתח עבור GCM).
  5. הלקוח שולח צומת (12 ע"י אזהרות אקראיות) ולאחר מכן הודעת מוצפנת AES-GCM בתוספת תג. Server decrypts and verifies.
  6. שרת שולחת תגובה באמצעות צומת חדש (לעולם אל תשתמשו באי-ces עם אותו מפתח).
  7. שני הצדדים יכולים להמשיך להחליף הודעות; במשך מפגשים ארוכים, להשתמש באותה תקופה במנגנון DH Handhake או מנגנון רפלק.

אבטחה Best Practices

  • (ב) ויקרא (ב"ד) ויקרא (בראשית י"ד): "ה' (ב)' (ב')'' (ב')')' (ב')''')'''''''''''')'''''''''''''''''''''''''')''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  • (FLT:0)Validate כל הנתונים שהתקבלו.FLT3 Check אורך, פרמטרים מרכזיים ציבוריים (למשל, להבטיח p הוא ראשי, g הוא גנרטור), ותגי HMAC לפני עיבוד.
  • (ב) ,0) ללא מפתחות קודרים או ברירת מחדל.אנדרל 1 תמיד משא ומתן על מפתחות טריים לפגישה כדי לספק סודיות מתקדמת מושלמת.
  • (ב) אם פענוח ה-HMAC נכשל או אימות HMAC נכשל, סגר את החיבור וההתאם לאירוע.
  • (ב) ,0) , [13] , עיין ב-[[1924]] ב[[1924]], ב[[1924]], [[1924]], [[1924]]]], [[1924]]]], [[1924]]]]]], [[1924]]]]]]]], [[1924]]]]]]]]
  • (FLT:0)Consider באמצעות TLS ולא פרוטוקול מותאם אישית.FLT 1 עבור מערכות ייצור, להסתמך על פרוטוקולים נבדקים היטב כמו TLS 1.3. בניית פרוטוקול מותאם אישית מאפס היא שגיאה-prone ולא מומלץ אלא אם כן יש לך מומחיות קריפטוגרפית עמוקה.

בדיקת הפרוטוקול

בדוק את היישום שלך על ידי הפעלת לקוח לשרת על אותה מכונה (localhost) ולוודא כי הודעות לפענח כראוי.לרשום שגיאות כגון ciphered ciphertext או nonces invalid כדי להבטיח שהפרוטוקול דוחה אותם. השתמש בכלים כמו Wireshark כדי לבדוק את התנועה רשת הגלומה ולאשש כי טקסט פשוט אינו גלוי.

מסקנה

בניית פרוטוקול תקשורת מאובטח ב- C היא תרגיל למידה מעולה, אבל זה דורש תשומת לב קפדנית לפרטים. על ידי מינוף המימושים המוכחים של OpenSSL של Diffie-Hellman, AES-GCM, ו- HMAC, אתה יכול ליצור מערכת המספקת סודיות, יושרה, אימות.תמיד לעקוב אחר שיטות יעילות הצפנה: שימוש אקראיות חזקות, להפיק מפתחות עם KDF, לא reuses, לא נבדק באופן יסודי, ולא משקף כל מידע על ידי יישום סטנדרטי של כל דבר אחר כל כך: 1.TL.