2013-05-07 14 views
9

में बाइट सरणी के लिए निजी कुंजी मैं निर्यात करने के लिए और आयात करने के लिए और बाइट सरणियों से निजी कुंजी के साथ प्रमाणपत्र उत्पन्न होती है और मैं किसी भी समस्या नहीं है जब तक कि मैं नेट ढांचा 4.0 का उपयोग की जरूरत के साथ प्रमाण पत्र और 4.5। मैं BouncyCastle लाइब्रेरी के साथ स्वयं हस्ताक्षरित प्रमाणपत्र उत्पन्न कर रहा हूं और फिर उन्हें .NET प्रारूप (X509Certificate2 ऑब्जेक्ट) में परिवर्तित कर रहा हूं। दुर्भाग्य से एक नए ढांचे के उन्नयन के साथ मैं निजी कुंजी निर्यात नहीं कर सकता। यहाँ कोड है:उत्पन्न नहीं निर्यात कर सकते हैं .net 4.0/4.5

using System; 
using System.Diagnostics; 
using System.Security.Cryptography; 
using System.Security.Cryptography.X509Certificates; 
using Org.BouncyCastle.Asn1.X509; 
using Org.BouncyCastle.Crypto; 
using Org.BouncyCastle.Crypto.Generators; 
using Org.BouncyCastle.Crypto.Parameters; 
using Org.BouncyCastle.Crypto.Prng; 
using Org.BouncyCastle.Math; 
using Org.BouncyCastle.Security; 
using Org.BouncyCastle.X509; 

namespace X509CertificateExport 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var certificate = Generate(); 
      var exported = certificate.Export(X509ContentType.Pfx); 
      var imported = new X509Certificate2(exported, (string)null, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); 

      Console.WriteLine("Certificate has private key: " + imported.HasPrivateKey); 
      Console.ReadKey(); 
     } 

     public static X509Certificate2 Generate() 
     { 
      var keyPairGenerator = new RsaKeyPairGenerator(); 
      var secureRandom = new SecureRandom(new CryptoApiRandomGenerator()); 
      keyPairGenerator.Init(new KeyGenerationParameters(secureRandom, 1024)); 
      var keyPair = keyPairGenerator.GenerateKeyPair(); 
      var publicKey = keyPair.Public; 
      var privateKey = (RsaPrivateCrtKeyParameters)keyPair.Private; 

      var generator = new X509V3CertificateGenerator(); 
      generator.SetSerialNumber(BigInteger.ProbablePrime(120, new Random())); 
      generator.SetSubjectDN(new X509Name("CN=Test")); 
      generator.SetIssuerDN(new X509Name("CN=Test")); 
      generator.SetNotAfter(DateTime.Now + new TimeSpan(10, 10, 10, 10)); 
      generator.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0))); 
      generator.SetSignatureAlgorithm("MD5WithRSA"); 
      generator.SetPublicKey(publicKey); 

      var newCert = generator.Generate(privateKey); 
      var dotNetPrivateKey = ToDotNetKey(privateKey); 
      var dotNetCert = new X509Certificate2(DotNetUtilities.ToX509Certificate(newCert)); 
      dotNetCert.PrivateKey = dotNetPrivateKey; 

      return dotNetCert; 
     } 

     public static AsymmetricAlgorithm ToDotNetKey(RsaPrivateCrtKeyParameters privateKey) 
     { 
      var rsaProvider = new RSACryptoServiceProvider(); 
      var parameters = new RSAParameters 
      { 
       Modulus = privateKey.Modulus.ToByteArrayUnsigned(), 
       P = privateKey.P.ToByteArrayUnsigned(), 
       Q = privateKey.Q.ToByteArrayUnsigned(), 
       DP = privateKey.DP.ToByteArrayUnsigned(), 
       DQ = privateKey.DQ.ToByteArrayUnsigned(), 
       InverseQ = privateKey.QInv.ToByteArrayUnsigned(), 
       D = privateKey.Exponent.ToByteArrayUnsigned(), 
       Exponent = privateKey.PublicExponent.ToByteArrayUnsigned() 
      }; 

      rsaProvider.ImportParameters(parameters); 
      return rsaProvider; 
     } 
    } 
} 

उत्पन्न प्रमाण पत्र को नज़दीक से देखने के बाद मैंने देखा है कि PrivateKey.CspKeyContainerInfo.Exportable झंडा .NET Framework 3.5 के लिए सही है, लेकिन बाद के संस्करणों के लिए फेंक देता है:

'Exportable' threw an exception of type 
'System.Security.Cryptography.CryptographicException'/Key does not exist 

मैं देखता हूं कि एकमात्र अंतर PrivateKey.CspKeyContainerInfo.m_parameters.Flags: .NET 3.5 - 'NoFlags'; .NET 4.5 - 'CreateEphemeralKey'। दस्तावेज़ीकरण बताता है कि 'CreateEphemeralKey' एक अस्थायी कुंजी बनाता है जो संबंधित आरएसए ऑब्जेक्ट बंद होने पर जारी किया जाता है। इसे 4.0 ढांचे के साथ पेश किया गया था और इससे पहले अस्तित्व में नहीं था। मैंने स्पष्ट रूप से सीएसपी पैरामीटर बनाकर इस ध्वज से छुटकारा पाने की कोशिश की है:

public static AsymmetricAlgorithm ToDotNetKey(RsaPrivateCrtKeyParameters privateKey) 
{ 
    var cspParams = new CspParameters 
    { 
     Flags = CspProviderFlags.UseMachineKeyStore 
    }; 

    var rsaProvider = new RSACryptoServiceProvider(cspParams); 
    // ... 

लेकिन बिना किसी किस्मत के। 'CreateEphemeralKey' को वैसे भी जोड़ा गया है, इसलिए मुझे परिणाम UseMachineKeyStore | CreateEphemeralKey झंडे के रूप में मिल रहा है और मुझे नहीं लगता कि मैं इसे कैसे हटा सकता हूं। क्या कोई तरीका है कि मैं इस ध्वज को अनदेखा कर सकता हूं और आमतौर पर निजी कुंजी के साथ निर्यात प्रमाणपत्र निर्यात कर सकता हूं?

+0

संभव डुप्लिकेट [डालने प्रमाणपत्र (privatekey के साथ) रूट में, LocalMachine प्रमाणपत्र संग्रह .NET में विफल रहता है 4] (http://stackoverflow.com/questions/3625624/inserting-certificate-with-privatekey-in -root-localmachine-circuit-store) – albertjan

उत्तर

12

मैंने देखा नहीं किया है कि CspKeyContainerInfo.CspParameters.KeyContainerName .NET 4.0 और .NET 4.5 में महत्वपूर्ण निर्माण के बाद खाली हो गया है, लेकिन .NET 3.5 में ऑटोजनरेटेड किया गया था। मैंने कंटेनर के लिए एक अनूठा नाम सेट किया है और अब मैं निजी कुंजी निर्यात करने में सक्षम हूं।

public static AsymmetricAlgorithm ToDotNetKey(RsaPrivateCrtKeyParameters privateKey) 
{ 
    var cspParams = new CspParameters 
    { 
      KeyContainerName = Guid.NewGuid().ToString(), 
      KeyNumber = (int)KeyNumber.Exchange, 
      Flags = CspProviderFlags.UseMachineKeyStore 
    }; 

    var rsaProvider = new RSACryptoServiceProvider(cspParams); 
    // ... 
की
+0

आप __the__ आदमी हैं! धन्यवाद! – albertjan

+0

यह एक अच्छा @ उपयोगकर्ता नाम, उपयोगकर्ता नाम है। –

+0

यह "ठीक करें" भी त्रुटि को हल: SSL प्रमाणपत्र जोड़ने में विफल रहा है, त्रुटि: 1312 एक निर्दिष्ट लॉग-ऑन सत्र मौजूद नहीं है। यह पहले ही समाप्त हो चुका है। – RcMan

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

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