सी में एक सुरक्षित संचार प्रोटोकॉल के निर्माण के लिए पूर्वापेक्षा

कार्यान्वयन में डाइविंग से पहले, यह सुनिश्चित करें कि आपके विकास के माहौल में सी कम्पाइलर (जीसीसी या क्लांग), सॉकेट प्रोग्रामिंग का बुनियादी ज्ञान और ओपनएसएसएल पुस्तकालय स्थापित है। ओपनएसएसएल क्रिप्टोग्राफिक एल्गोरिदम के मजबूत कार्यान्वयन को प्रदान करता है, जिससे इसे सी. लिनक्स में सुरक्षित संचार के लिए मानक विकल्प बनाया गया है, अपने पैकेज मैनेजर (जैसे, ) के माध्यम से ओपनएसएसएल स्थापित किया गया है। विंडोज पर, प्रीकंपाइल्ड बायनेरीज़ का उपयोग करें या स्रोत से निर्माण करें। टीसीपी / आईपी सॉकेट के साथ निष्ठा और ग्राहक-सर्वर मॉडल को भी माना जाता है।

Cryptographic Building Blocks

एक सुरक्षित संचार प्रोटोकॉल तीन स्तंभों पर आराम करता है: गोपनीयता, अखंडता और प्रमाणीकरण। गोपनीयता एन्क्रिप्शन के माध्यम से हासिल की जाती है, यह सुनिश्चित करता है कि केवल इच्छित प्राप्तकर्ता संदेश पढ़ सकता है। अखंडता यह सुनिश्चित करती है कि डेटा को पारगमन में बदल नहीं दिया गया है। प्रमाणीकरण पक्षों की पहचान को सत्यापित करता है। एक कस्टम प्रोटोकॉल में, आप आम तौर पर सममित एन्क्रिप्शन को जोड़ते हैं, संदेश प्रमाणीकरण कोड (एचमैक) के साथ है, और डिफी-हेलमैन जैसे प्रमुख विनिमय तंत्र।

AES के साथ सममित एन्क्रिप्शन

उन्नत एन्क्रिप्शन मानक (AES) सबसे व्यापक रूप से इस्तेमाल किया जाने वाला सिफर है। यह 128-बिट ब्लॉकों पर काम करता है और 128, 192 या 256 बिट्स के प्रमुख आकार का समर्थन करता है। सुरक्षित संचार के लिए, गैलोइस /काउंटर मोड (GCM) में AES पसंद करते हैं, जो एक ही ऑपरेशन में गोपनीयता और अखंडता दोनों प्रदान करता है। ओपनएसएसएल का EVP इंटरफ़ेस एईएस-GCM के साथ डेटा को एन्क्रिप्ट और डिक्रिप्ट करने के लिए सीधा बनाता है।

डिफ़ी-हेलमैन के साथ कुंजी एक्सचेंज

सुरक्षित रूप से एक असुरक्षित चैनल पर एक साझा गुप्त पर सहमत होने के लिए, डिफी-हेलमैन (डीएच) कुंजी विनिमय का उपयोग करें। दोनों पक्ष निजी कुंजी उत्पन्न करते हैं और सार्वजनिक मापदंडों का आदान-प्रदान करते हैं, फिर एक सामान्य रहस्य की गणना करते हैं। Diffie-Hellman[ एक आदमी-इन-मध्य हमलों के लिए असुरक्षित है, अगर प्रमाणित नहीं किया जाता है, तो आप बाद में डिजिटल हस्ताक्षर या पूर्व साझा कुंजी के साथ इस का विस्तार कर सकते हैं। उत्पादन उपयोग के लिए, सही आगे की गोपनीयता प्रदान करने के लिए ephemeral Diffie-Hellman (DHE) को रोजगार पर विचार करें।

HMAC के साथ संदेश अखंडता और प्रमाणीकरण

यह सत्यापित करने के लिए कि एक संदेश को छेड़छाड़ नहीं की गई है, प्रत्येक एन्क्रिप्टेड सिफरटेक्स्ट को हैश आधारित संदेश प्रमाणीकरण कोड (एचमैक) को प्रस्तुत करता है। एचमैक एक साझा गुप्त कुंजी और एक क्रिप्टोग्राफिक हैश फंक्शन (जैसे, SHA-256) का उपयोग करता है। रिसीवर प्राप्त डेटा पर एचमैक को पुनः संयोजित करता है और इसे प्रेषित मूल्य पर तुलना करता है। यह कदम फिर से खेलना और छेड़छाड़ के हमलों को रोकता है। वैकल्पिक रूप से, एईएस-जीसीएम में एक प्रमाणीकरण टैग शामिल है जो समान उद्देश्य को कार्य करता है, प्रोटोकॉल को सरल बनाता है।

अपने सी परियोजना में OpenSSL की स्थापना

OpenSSL को सावधानीपूर्वक आरंभीकरण की आवश्यकता होती है। अपने कार्यक्रम के प्रारंभ में आवश्यक हेडर और कॉल और शामिल करें। त्रुटि हैंडलिंग के लिए, ] और का उपयोग करें। लिंक करते समय, अपने compiler झंडे के लिए जोड़ें। एक न्यूनतम सेटअप इस तरह दिखता है:

#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();
}

टीसीपी सॉकेट लेयर का निर्माण

अपने प्रोटोकॉल के लिए अंतर्निहित परिवहन टीसीपी होगा, जो विश्वसनीय, आदेशित डिलीवरी प्रदान करता है। एक सर्वर बनाएं जो आने वाले कनेक्शन और एक क्लाइंट को सुनता है जो हैंडशेक शुरू करता है। ] के साथ मानक POSIX सॉकेट का उपयोग करें, , , ], सर्वर साइड पर, और [FLT: 11]]], [[FLT: 12]]]]]] क्लाइंट साइड पर। उपयोग के बाद त्रुटियों को सुंदर ढंग से और बंद करने के लिए याद रखें।

सर्वर उदाहरण कंकाल

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

क्लाइंट उदाहरण कंकाल

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

डिफी-हेलमैन की एक्सचेंज को कार्यान्वित करना

टीसीपी कनेक्शन की स्थापना के बाद, क्लाइंट और सर्वर एक डीएच कुंजी विनिमय करते हैं। प्रत्येक पक्ष ओपनएसएसएल के एपीआई का उपयोग करके एक डीएच कुंजी जोड़ी उत्पन्न करता है। सार्वजनिक कुंजी सॉकेट पर भेजी जाती है, और दोनों पक्ष एक साझा गुप्त को ] का उपयोग करके निष्क्रिय कर देते हैं। सादगी के लिए, एक निश्चित प्राइम ग्रुप (जैसे, का उपयोग करके ]]] के मापदंडों के साथ किया जाता है। एक वास्तविक प्रोटोकॉल में, आप समूह पर बातचीत करेंगे या पूर्व-परिभाषित मापदंडों का उपयोग करेंगे।

// 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 के साथ) hashed किया जा सकता है।

AES-GCM के साथ संदेश एन्क्रिप्ट करना और डिक्रिप्ट करना

AES-GCM पसंदीदा मोड है क्योंकि यह एक ऑपरेशन में एन्क्रिप्शन और एक प्रमाणीकरण टैग दोनों प्रदान करता है। [[FLT: 22]] के साथ ओपनएसएसएल के [[FLT: 21] का प्रयोग करें। आपको 12-byte nonce (IV) की आवश्यकता है और डीएच साझा रहस्य से ली गई 256-bit कुंजी। सिफरटेक्स्ट को चंकड़ों में बनाया गया है, और अंतिम अद्यतन के बाद, आप 16-byte टैग को पुनः प्राप्त करते हैं। नॉन्स, सिफरटेक्स्ट और टैग को एक साथ भेजें। रिसीवर करता है, टैग सेट करता है, और डिक्रिप्ट करता है। यदि टैग सत्यापन विफल हो जाता है, तो संदेश अस्वीकार कर दिया जाता है।

// 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 टैग) के साथ ईमानदारी जोड़ना

यदि आप AES-GCM का उपयोग नहीं करते हैं, तो आप AES-CBC के साथ एन्क्रिप्ट कर सकते हैं और फिर एक HMAC को ciphertext पर संकलित कर सकते हैं। SHA-256 के साथ OpenSSL से का उपयोग करें। HMAC को सिफरटेक्स्ट के बाद परिशिष्ट करें। रिसीवर को पुन:प्राप्ति और तुलना की आवश्यकता है। इस दृष्टिकोण को दो कुंजी की आवश्यकता है: एन्क्रिप्शन के लिए एक, HMAC के लिए एक। दोनों को साझा गुप्त से एक कुंजी विचलन समारोह (KDF) का उपयोग करते हुए रखें। हालांकि, AES-GCM एक अलग HMAC की आवश्यकता को समाप्त करता है, जटिलता और संभावित गलतियों को कम करता है।

इसे एक साथ रखना: पूर्ण वर्कफ़्लो

  1. क्लाइंट और सर्वर के बीच टीसीपी कनेक्शन स्थापित करें।
  2. दोनों पक्ष इफेमेरल डिफी -हेलमैन कुंजी जोड़े उत्पन्न करते हैं।
  3. सार्वजनिक कुंजी को एक्सचेंज करें और साझा रहस्य को compute करें।
  4. एक 256-bit AES कुंजी और एक 256-bit HMAC कुंजी (या GCM के लिए एक ही कुंजी का उपयोग करें) डेरिव करें।
  5. ग्राहक एक नॉन्सी (12 बाइट्स यादृच्छिक) भेजता है और फिर एईएस-जीसीएम एन्क्रिप्टेड संदेश प्लस टैग। सर्वर डिक्रिप्ट और सत्यापित करता है।
  6. सर्वर एक नई नॉन्से (कभी भी उसी कुंजी के साथ गैर-विक्रय का उपयोग नहीं करता) का उपयोग करके प्रतिक्रिया भेजता है।
  7. दोनों पक्षों को संदेश का आदान-प्रदान जारी रख सकते हैं; लंबे सत्रों के लिए, समय-समय पर उसी डीएच हथशक या एक ratchet तंत्र का उपयोग करते हुए बंदी।

सुरक्षा सर्वश्रेष्ठ अभ्यास

  • ]]]Use strong random number generator. OpenSSL से कुंजी, गैर-विक्रय और DH निजी कुंजी उत्पन्न करने के लिए कॉल या ]]] क्रिप्टोग्राफिक प्रयोजनों के लिए।
  • ]सभी डेटा प्राप्त करने की घोषणा लंबाई की जाँच करें, सार्वजनिक कुंजी मापदंडों (जैसे, p को सुनिश्चित करना प्राइम है, जी एक जनरेटर है), और HMAC टैग प्रसंस्करण से पहले।
  • Avoid hardcoded कुंजी या डिफ़ॉल्ट। हमेशा सही आगे गोपनीयता प्रदान करने के लिए प्रति सत्र नए कुंजी बातचीत।
  • Handle त्रुटियों को gracefully. यदि डिक्रिप्शन विफल हो जाता है या HMAC सत्यापन विफल हो जाता है, तो कनेक्शन बंद कर देता है और घटना लॉग इन करता है। खुलासा नहीं करता कि विफलता क्यों हुई है।
  • Keep निर्भरता अद्यतन किया गया। ] नियमित रूप से अद्यतन OpenSSL पहचाने जाने वाले भेद्यता को पैच करने के लिए। OpenSSL प्रलेखन deprecation और सर्वोत्तम प्रथाओं पर मार्गदर्शन प्रदान करता है।
  • Consider एक कस्टम प्रोटोकॉल के बजाय TLS का उपयोग करते हैं। उत्पादन प्रणालियों के लिए, TLS 1.3 जैसे अच्छी तरह से प्रमाणित प्रोटोकॉल पर भरोसा करते हैं। स्क्रैच से एक कस्टम प्रोटोकॉल का निर्माण त्रुटि-प्रवण है और जब तक आपके पास गहरी क्रिप्टोग्राफ़िक विशेषज्ञता नहीं है, तब तक अनुशंसा नहीं की जाती है।

प्रोटोकॉल का परीक्षण

उसी मशीन (स्थानीय होस्ट) पर क्लाइंट और सर्वर चलाने के द्वारा अपने कार्यान्वयन का परीक्षण करें और यह सत्यापित करें कि संदेशों को सही ढंग से डिक्रिप्ट करें। यह सुनिश्चित करने के लिए कि प्रोटोकॉल उन्हें अस्वीकार करता है, जैसे छेड़छाड़ किए गए सिफरटेक्स्ट या अवैध गैर-छिद्रों का परिचय दें। कच्चे नेटवर्क यातायात का निरीक्षण करने के लिए वायरशर्क जैसे उपकरणों का उपयोग करें और पुष्टि करें कि सादेटेक्स्ट दिखाई नहीं देता है। यूनिट परीक्षण के लिए, सॉकेट परत का मजाक उड़ाएं और अलग से क्रिप्टोग्राफिक प्राइमिटिव्स का परीक्षण करें। ओपनएसएसएल के डीबगिंग मध्यवर्ती मूल्यों मैच अपेक्षित आउटपुट को सत्यापित करने में मदद कर सकता है।

निष्कर्ष

C में एक सुरक्षित संचार प्रोटोकॉल का निर्माण एक उत्कृष्ट शिक्षण अभ्यास है, लेकिन इसके लिए विस्तार से सावधानीपूर्वक ध्यान देने की आवश्यकता है। Diffie-Hellman, AES-GCM, और HMAC के ओपनएसएसएल के सिद्ध कार्यान्वयन का लाभ उठाकर, आप एक ऐसा सिस्टम बना सकते हैं जो गोपनीयता, अखंडता और प्रमाणीकरण प्रदान करता है। हमेशा क्रिप्टोग्राफिक सर्वोत्तम प्रथाओं का पालन करें: एक KDF के साथ मजबूत यादृच्छिकता, निष्क्रिय सत्र कुंजी का उपयोग करें, कभी भी गैर-विरोधी उपयोग नहीं किया जाता है, और सभी डेटा को पूरी तरह से मान्य नहीं किया जाता है। एक सीखने की परियोजना से परे कुछ के लिए, एक मानक प्रोटोकॉल को अपनाने पर विचार करें जैसे TLS 1.3 [[FLT:]]]]]]]