2008-11-02 19 views
57

का उपयोग कर प्रोग्रामेटिक रूप से X509 प्रमाणपत्र बनाएं मेरे पास एक सी/सी ++ एप्लिकेशन है और मुझे एक सार्वजनिक और निजी कुंजी दोनों युक्त X509 पेम प्रमाणपत्र बनाने की आवश्यकता है। प्रमाणपत्र स्वयं हस्ताक्षरित, या हस्ताक्षरित हो सकता है, कोई फर्क नहीं पड़ता।ओपनएसएसएल

मैं इसे एक ऐप के अंदर करना चाहता हूं, कमांड लाइन से नहीं।

ओपनएसएसएल फ़ंक्शन मेरे लिए क्या करेंगे? कोई भी नमूना कोड बोनस है!

उत्तर

36

आपको पहले शब्दावली और तंत्र से परिचित होना होगा।

एक एक्स.50 9 प्रमाणपत्र, परिभाषा के अनुसार, इसमें एक निजी कुंजी शामिल नहीं है। इसके बजाए, यह सार्वजनिक कुंजी का सीए-हस्ताक्षरित संस्करण है (सीए हस्ताक्षर में रखे गए किसी विशेष गुण के साथ)। पीईएम प्रारूप वास्तव में कुंजी और प्रमाण पत्र के अलग-अलग भंडारण का समर्थन करता है - हालांकि आप दोनों को जोड़ सकते हैं।

किसी भी मामले में, आपको एक कुंजी और स्वयं हस्ताक्षरित प्रमाणपत्र बनाने के लिए ओपनएसएसएल एपीआई के 20+ विभिन्न कार्यों को आमंत्रित करने की आवश्यकता होगी। ओपनएसएसएल स्रोत में एक उदाहरण है, demos/x509/mkcert.c

अधिक विस्तृत उत्तर के लिए, कृपया नीचे Nathan Osman's explanation देखें।

+0

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

+0

धन्यवाद! प्रदत्त लिंक के कारण इस उत्तर को चुना गया। –

0

system के माध्यम से ऐसा करने का कोई भी मौका आपके ऐप के भीतर से कॉल करता है? ऐसा करने के लिए कई अच्छे कारणों:

  • लाइसेंसिंग: openssl निष्पादन यकीनन कॉलिंग आपके आवेदन से अलग करती है और कुछ लाभ प्रदान कर सकता है। अस्वीकरण: इस पर एक वकील से परामर्श लें।

  • प्रलेखन: OpenSSL अभूतपूर्व कमांड लाइन प्रलेखन है कि बहुत एक संभावित जटिल उपकरण को सरल के साथ आता है।

  • टेस्टेबिलिटी: आप ओपनएसएसएल को कमांड लाइन से तब तक व्यायाम कर सकते हैं जब तक आप समझ नहीं लेते कि वास्तव में आपके कैर्ट कैसे बनाएं। विकल्प के लॉट हैं; इस पर एक दिन तक खर्च करने की उम्मीद है जब तक आप सभी विवरण सही नहीं प्राप्त करते। उसके बाद, आपके ऐप में कमांड को शामिल करना मुश्किल है।

आप एपीआई का उपयोग करने, www.openssl.org पर openssl-dev डेवलपर्स सूची की जांच का निर्णय लेते हैं।

गुड लक!

+0

ओपनएसएसएल जीपीएल http://www.openssl.org/source/license.html – Zoredache

+5

ओपनएसएसएल एक अपाचे स्टाइल लाइसेंस के तहत लाइसेंस है, इसका उपयोग किसी भी अन्य गैर-प्रतिलिपि लाइसेंस की तरह वाणिज्यिक ऐप्स में किया जा सकता है ।लोग अभी भी यह सुनिश्चित करने के लिए एक वकील से परामर्श करना चाहेंगे कि वे जो कुछ भी करते हैं वह ठीक है, लेकिन इसमें जीपीएल संबंधित मुद्दे नहीं हैं –

+0

नोट किया गया और अपडेट किया गया - धन्यवाद। बंद-स्रोत कोड से ओपन-सोर्स का पृथक्करण आम तौर पर एक अच्छा विचार है, और जब तक कि दक्षता महत्वपूर्ण महत्व न हो, अन्य कारण स्टैंड-अलोन ओपनस्ल उपयोगिता का उपयोग करने के लिए एक अच्छा मामला बनाते हैं। –

0

बहुत ही सरल ट्यूटोरियल डिजिटल प्रमाणपत्र http://publib.boulder.ibm.com/infocenter/rsthelp/v8r0m0/index.jsp?topic=/com.ibm.rational.test.lt.doc/topics/tcreatecertopenssl.html

अपने कोड से इन आदेशों को क्रियान्वित करने के बारे में बनाने के लिए मैं यकीन नहीं है।

+0

मुझसे डाउनवोट - यह एक टिप्पणी की तरह लगता है, जवाब नहीं। यदि आपने उस लिंक से महत्वपूर्ण तथ्यों को शामिल किया है, तो यह एक उत्तर बन जाएगा :-) –

139

मुझे एहसास है कि यह बहुत देर हो चुकी है (और लंबा) उत्तर। लेकिन इस सवाल पर खोज इंजन परिणामों में कितना अच्छा लगता है, मुझे लगा कि यह एक सभ्य उत्तर लिखने लायक हो सकता है।

नीचे जो कुछ आप पढ़ेंगे, उसे 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 देख सकते हैं।

+0

उत्कृष्ट उत्तर और स्पष्टीकरण के लिए धन्यवाद! केवल एक छोटा सा संदेह: क्या यह वाक्य है 'अब हमें हमारे द्वारा प्रमाणित कुंजी का उपयोग करके हमारे प्रमाण पत्र के लिए सार्वजनिक कुंजी सेट करने की आवश्यकता है:' एक टाइपो? क्या 'सार्वजनिक कुंजी' निजी कुंजी नहीं होनी चाहिए? –

+2

मुझे अंत में fclose (f) जोड़ना पड़ा। अन्यथा फ़ाइल लिखा जा रहा था 0 बी –

+0

@QamarSuleiman: अच्छी पकड़। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^