मुझे एहसास है कि यह बहुत देर हो चुकी है (और लंबा) उत्तर। लेकिन इस सवाल पर खोज इंजन परिणामों में कितना अच्छा लगता है, मुझे लगा कि यह एक सभ्य उत्तर लिखने लायक हो सकता है।
नीचे जो कुछ आप पढ़ेंगे, उसे this demo और ओपनएसएसएल दस्तावेज़ों से उधार लिया जाता है। नीचे दिया गया कोड सी और सी ++ दोनों पर लागू होता है।
इससे पहले कि हम वास्तव में प्रमाण पत्र बना सकें, हमें एक निजी कुंजी बनाना होगा। ओपनएसएसएल स्मृति में एल्गोरिदम-स्वतंत्र निजी कुंजी संग्रहीत करने के लिए EVP_PKEY
संरचना प्रदान करता है। यह संरचना openssl/evp.h
में घोषित की गई है लेकिन openssl/x509.h
(जिसे हमें बाद में आवश्यकता होगी) द्वारा शामिल किया गया है, इसलिए आपको वास्तव में हेडर को स्पष्ट रूप से शामिल करने की आवश्यकता नहीं है।
आदेश में एक EVP_PKEY
संरचना का आवंटन करने के लिए हम EVP_PKEY_new
का उपयोग करें:
EVP_PKEY * pkey;
pkey = EVP_PKEY_new();
भी संरचना को मुक्त कराने के लिए एक इसी समारोह नहीं है - EVP_PKEY_free
- जो एक तर्क स्वीकार करता है: EVP_PKEY
संरचना ऊपर प्रारंभ।
अब हमें एक कुंजी उत्पन्न करने की आवश्यकता है। हमारे उदाहरण के लिए, हम एक आरएसए कुंजी उत्पन्न करेंगे। यह RSA_generate_key
फ़ंक्शन के साथ किया जाता है जिसे openssl/rsa.h
में घोषित किया गया है। यह फ़ंक्शन एक पॉइंटर को RSA
संरचना में देता है।
समारोह का एक सरल मंगलाचरण इस प्रकार दिखाई देंगे:
RSA * rsa;
rsa = RSA_generate_key(
2048, /* number of bits for the key - 2048 is a sensible value */
RSA_F4, /* exponent - RSA_F4 is defined as 0x10001L */
NULL, /* callback - can be NULL if we aren't displaying progress */
NULL /* callback argument - not needed in this case */
);
हैं RSA_generate_key
के रिटर्न मान NULL
है, तो कुछ गलत हो गया। यदि नहीं, तो हम अब कोई RSA कुंजी है, और हम पहले से हमारे EVP_PKEY
संरचना को असाइन कर सकते हैं:
EVP_PKEY_assign_RSA(pkey, rsa);
जब EVP_PKEY
संरचना मुक्त हो जाता है RSA
संरचना स्वचालित रूप से मुक्त हो जाएगा।
अब प्रमाण पत्र के लिए।
ओपनएसएसएल स्मृति में x509 प्रमाण पत्र का प्रतिनिधित्व करने के लिए X509
संरचना का उपयोग करता है। इस संरचना की परिभाषा openssl/x509.h
में है। पहला कार्य जिसकी हमें आवश्यकता होगी X509_new
है। इसका उपयोग अपेक्षाकृत सरल है:
X509 * x509;
x509 = X509_new();
EVP_PKEY
साथ भी थी, वहाँ संरचना को मुक्त कराने के लिए एक इसी समारोह है - X509_free
।
अब हम कुछ X509_*
फ़ंक्शन का उपयोग प्रमाण पत्र के कुछ गुणों को सेट करने की जरूरत है:
ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
यह '1' के लिए हमारी प्रमाण पत्र की क्रम संख्या निर्धारित करता है। कुछ ओपन-सोर्स HTTP सर्वर '0' के सीरियल नंबर के साथ प्रमाण पत्र स्वीकार करने से इनकार करते हैं, जो डिफ़ॉल्ट है। अगला चरण उस समय की अवधि निर्दिष्ट करना है जिसके दौरान प्रमाणपत्र वास्तव में मान्य है।
X509_gmtime_adj(X509_get_notBefore(x509), 0);
X509_gmtime_adj(X509_get_notAfter(x509), 31536000L);
पहली पंक्ति को वर्तमान समय पर प्रमाण पत्र के notBefore
संपत्ति सेट: हम निम्न दो समारोह के साथ कहता है। (X509_gmtime_adj
फ़ंक्शन वर्तमान समय में निर्दिष्ट संख्याओं को जोड़ता है - इस मामले में कोई नहीं।) दूसरी पंक्ति प्रमाणपत्र से notAfter
प्रॉपर्टी को अब से 365 दिनों तक सेट करती है (60 सेकंड * 60 मिनट * 24 घंटे * 365 दिन)।
X509_set_pubkey(x509, pkey);
इस के बाद से एक स्व-हस्ताक्षरित प्रमाणपत्र है, हम जारीकर्ता का नाम के नाम पर सेट:
अब हम कुंजी हम पहले उत्पन्न का उपयोग कर हमारे प्रमाण पत्र के लिए सार्वजनिक कुंजी निर्धारित करने की आवश्यकता विषय।
X509_NAME * name;
name = X509_get_subject_name(x509);
आप पहले कभी कमांड लाइन पर एक स्व-हस्ताक्षरित प्रमाणपत्र बना लिया है, तो आप शायद एक देश कोड के लिए कहा जा रहा है याद है: कि प्रक्रिया में पहला कदम विषय नाम पाने के लिए है।
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
(unsigned char *)"CA", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,
(unsigned char *)"MyCompany Inc.", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
(unsigned char *)"localhost", -1, -1, 0);
(क्योंकि मैं कनाडा हूँ और कि हमारे देश है मैं मान 'सीए' का उपयोग कर रहा यहाँ: यहां हम इसके साथ प्रदान संगठन ('ओ') और आम नाम ('सीएन') के साथ है । कोड भी ध्यान रखें कि पैरामीटर # 4 जरूरतों को स्पष्ट रूप से unsigned char *
लिए डाली जा करने के लिए)
अब हम वास्तव में जारीकर्ता नाम सेट कर सकते हैं:।
X509_set_issuer_name(x509, name);
और अंत में हम पर हस्ताक्षर करने की प्रक्रिया को करने के लिए तैयार हैं। हम पहले से जेनरेट की गई कुंजी के साथ X509_sign
पर कॉल करते हैं। इस के लिए कोड दर्दनाक सरल है:
X509_sign(x509, pkey, EVP_sha1());
ध्यान दें कि हम SHA-1 हैशिंग कलन विधि का उपयोग कर रहे हैं कुंजी हस्ताक्षर करने के लिए। यह mkcert.c
डेमो से अलग है जो मैंने इस उत्तर की शुरुआत में उल्लेख किया है, जो एमडी 5 का उपयोग करता है।
अब हमारे पास एक स्व-हस्ताक्षरित प्रमाणपत्र है! लेकिन हम अभी तक नहीं किए गए हैं - हमें इन फ़ाइलों को डिस्क पर लिखना होगा। शुक्र है कि ओपनएसएसएल ने हमें PEM_*
कार्यों के साथ भी कवर किया है जो openssl/pem.h
में घोषित किए गए हैं। हमारी निजी कुंजी को सहेजने के लिए हमें पहले की आवश्यकता होगी PEM_write_PrivateKey
।
FILE * f;
f = fopen("key.pem", "wb");
PEM_write_PrivateKey(
f, /* write the key to the file we've opened */
pkey, /* our key from earlier */
EVP_des_ede3_cbc(), /* default cipher for encrypting the key on disk */
"replace_me", /* passphrase required for decrypting the key on disk */
10, /* length of the passphrase string */
NULL, /* callback for requesting a password */
NULL /* data to pass to the callback */
);
आप निजी कुंजी एन्क्रिप्ट करने के लिए नहीं करना चाहते हैं, तो बस ऊपर तीसरे और चौथे पैरामीटर के लिए NULL
गुजरती हैं। किसी भी तरह से, आप निश्चित रूप से यह सुनिश्चित करना चाहते हैं कि फ़ाइल विश्व-पठनीय नहीं है। (यूनिक्स उपयोगकर्ताओं के लिए, इसका मतलब है chmod 600 key.pem
।)
Whew! अब हम एक समारोह में हैं - हमें प्रमाण पत्र को डिस्क पर लिखना होगा। समारोह हम इस बात के लिए की जरूरत है PEM_write_X509
है:
FILE * f;
f = fopen("cert.pem", "wb");
PEM_write_X509(
f, /* write the certificate to the file we've opened */
x509 /* our certificate */
);
और हम काम हो गया! उम्मीद है कि इस उत्तर में दी गई जानकारी आपको सब कुछ कैसे काम करती है, इस बारे में कोई अंदाजा देने के लिए पर्याप्त है, हालांकि हमने ओपनएसएसएल की सतह को मुश्किल से खरोंच कर दिया है।
उन लोगों के लिए जो ऊपर दिए गए सभी कोड वास्तविक एप्लिकेशन में दिखने में रुचि रखते हैं, मैंने एक गिस्ट (सी ++ में लिखा) को फेंक दिया है जिसे आप here देख सकते हैं।
हां - मुझे एसएसएल अवधारणाओं के साथ खुद को और परिचित करने की आवश्यकता है। मैं उदाहरण की जांच करूंगा, लिंक के लिए धन्यवाद (लिंक में कोई समस्या है, लेकिन मैं इसे समझूंगा।) मैंने कुछ सामानों के लिए क्रिप्टो ++ का भी उपयोग किया है, यह इस मामले में ओपनएसएसएल की तुलना में उपयोग करने के लिए ईज़ीर हो सकता है। –
धन्यवाद! प्रदत्त लिंक के कारण इस उत्तर को चुना गया। –