2009-05-21 15 views
9

के बिना X.50 9 प्रमाणपत्र निर्यात करना मैंने सोचा कि यह सीधा होगा लेकिन स्पष्ट रूप से यह नहीं है। मेरे पास एक प्रमाण पत्र स्थापित है जिसमें निजी कुंजी, निर्यात योग्य है, और मैं इसे प्रोग्राम की रूप से केवल सार्वजनिक कुंजी के साथ निर्यात करना चाहता हूं। दूसरे शब्दों में, मैं प्रमाण पत्र के माध्यम से निर्यात करते समय और सीईआर को निर्यात करते समय "निजी कुंजी निर्यात न करें" का चयन करने के बराबर परिणाम प्राप्त करना चाहता हूं।निजी कुंजी

ऐसा लगता है कि सभी X509Certificate2. निर्यात विधियां निजी कुंजी को निर्यात करती हैं, जैसे कि यह मौजूद है, जैसा कि पीकेसीएस # 12 है, जो कि मैं चाहता हूं कि विपरीत है।

क्या इसे पूरा करने के लिए सी # का उपयोग करने का कोई तरीका है, या क्या मुझे कैपिकॉम में खुदाई शुरू करने की आवश्यकता है?

उत्तर

17

किसी और के लिए जो इस पर ठोकर खा सकता है, मैंने इसे समझ लिया। यदि आप X509ContentType.Cert को पहले (और केवल) पैरामीटर के रूप में X509Certificate.Export पर निर्दिष्ट करते हैं, तो यह केवल सार्वजनिक कुंजी निर्यात करता है। दूसरी तरफ, X509ContentType.Pfx निर्दिष्ट करने पर निजी कुंजी शामिल है यदि कोई मौजूद है।

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

+0

क्या आप जानते हैं पूरे प्रमाण पत्र के बिना केवल निजी कुंजी निर्यात करने के लिए एक रास्ता है तो कर ?, मैं बाइट सरणी के रूप में निजी कुंजी निकलने के लिए है, और मैं न इसे करने का कोई तरीका ढूंढें .... – RRR

+2

@RRR: जो कुछ भी आप करने की कोशिश कर रहे हैं, मैं इसके खिलाफ सलाह दूंगा क्योंकि प्रमाण पत्र की "निजी कुंजी" केवल बाइट सरणी से कहीं अधिक है, यह एक क्रिप्टोग्राफिक * एल्गोरिदम * है, विशेष रूप से एक 'असममित एल्गोरिदम', और विभिन्न प्रमाणपत्रों में पूरी तरह से अलग-अलग एल्गोरिदम हो सकते हैं। यदि आप इस जानकारी को खो देते हैं, तो सार्वजनिक कुंजी द्वारा एन्क्रिप्टेड/हस्ताक्षरित कुछ भी पुनर्निर्माण और डिक्रिप्ट/सत्यापित करना बहुत मुश्किल होगा। यदि आप वास्तव में इसके साथ गड़बड़ करने की कोशिश करना चाहते हैं, तो 'X509Certificate2.PrivateKey' देखें और वहां से कार्य करें। – Aaronaught

+1

@ हारून: आप आमतौर पर प्रमाण पत्र के साथ निजी कुंजी निर्यात नहीं करना चाहते हैं। निजी कुंजी एक बारीकी से आयोजित रहस्य रहना चाहिए। आप केवल निजी प्रमाणपत्र वाले निजी कुंजी के साथ हस्ताक्षरित कुछ भी सत्यापित कर सकते हैं - प्रमाण पत्र में केवल सार्वजनिक कुंजी होती है, और यह हस्ताक्षर सत्यापित करने के लिए आवश्यक है। आप आम तौर पर डेटा एन्क्रिप्ट करने के लिए निजी कुंजी का उपयोग नहीं करना चाहते हैं। साथ ही, निजी और सार्वजनिक कुंजी अदला-बदली नहीं हैं - एक सार्वजनिक कुंजी दी गई है, यह निजी कुंजी का अनुमान लगाने के लिए असंभव है, लेकिन इसके विपरीत नहीं। तो, उस निजी कुंजी को घर पर रखें। –

6

मैं निम्नलिखित कार्यक्रम अपने आप को आश्वस्त प्रमाण पत्र की RawData संपत्ति केवल सार्वजनिक कुंजी है कि के लिए उपयोगी (MSDN इस पर स्पष्ट नहीं है) मिल गया, और X509ContentType.Cert बनाम X509ContentType.Pfx काम करता है के बारे में ऊपर जवाब के रूप में उम्मीद है कि:

using System; 
using System.Linq; 
using System.IdentityModel.Tokens; 
using System.Security.Cryptography.X509Certificates; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var certPath = @"C:\blah\somecert.pfx"; 
     var certPassword = "somepassword"; 

     var orig = new X509Certificate2(certPath, certPassword, X509KeyStorageFlags.Exportable); 
     Console.WriteLine("Orig : RawData.Length = {0}, HasPrivateKey = {1}", orig.RawData.Length, orig.HasPrivateKey); 

     var certBytes = orig.Export(X509ContentType.Cert); 
     var certA = new X509Certificate2(certBytes); 
     Console.WriteLine("cert A : RawData.Length = {0}, HasPrivateKey = {1}, certBytes.Length = {2}", certA.RawData.Length, certA.HasPrivateKey, certBytes.Length); 

     // NOTE that this the only place the byte count differs from the others 
     certBytes = orig.Export(X509ContentType.Pfx); 
     var certB = new X509Certificate2(certBytes); 
     Console.WriteLine("cert B : RawData.Length = {0}, HasPrivateKey = {1}, certBytes.Length = {2}", certB.RawData.Length, certB.HasPrivateKey, certBytes.Length); 

     var keyIdentifier = (new X509SecurityToken(orig)).CreateKeyIdentifierClause<X509RawDataKeyIdentifierClause>(); 
     certBytes = keyIdentifier.GetX509RawData(); 
     var certC = new X509Certificate2(certBytes); 
     Console.WriteLine("cert C : RawData.Length = {0}, HasPrivateKey = {1}, certBytes.Length = {2}", certC.RawData.Length, certC.HasPrivateKey, certBytes.Length); 

     Console.WriteLine("RawData equals original RawData: {0}", certC.RawData.SequenceEqual(orig.RawData)); 

     Console.ReadLine(); 
    } 
} 

यह आउटपुट निम्नलिखित:

 
Orig : RawData.Length = 1337, HasPrivateKey = True 
cert A : RawData.Length = 1337, HasPrivateKey = False, certBytes.Length = 1337 
cert B : RawData.Length = 1337, HasPrivateKey = True, certBytes.Length = 3187 
cert C : RawData.Length = 1337, HasPrivateKey = False, certBytes.Length = 1337 
RawData equals original RawData: True 
संबंधित मुद्दे