2016-12-22 31 views
9

Vì vậy, dưới đây bạn sẽ tìm thấy mã của tôi tạo chứng chỉ tự ký với khóa riêng ở đó. Nó được lưu trữ trong cửa hàng người dùng. Bây giờ khi tôi sử dụng công cụ mmc tôi chỉ có thể xuất khóa riêng tư từ chứng chỉ? Tôi nghĩ đó là một lá cờ bạn phải thêm rõ ràng khi tạo cert?Cách khóa khóa cá nhân trong chứng chỉ không thể xuất được C#

Vì vậy, điều tôi muốn biết là, làm cách nào để thay đổi mã này để khóa riêng tư không thể xuất được thông qua mmc nữa.

Code:

public static X509Certificate2 GenerateSelfSignedCertificateNoCA(string subjectName, string issuerName) 
{ 
     const int keyStrength = 2048; 

     // Generating Random Numbers 
     CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator(); 
     SecureRandom random = new SecureRandom(randomGenerator); 

     // The Certificate Generator 
     X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator(); 

     // Serial Number 
     BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); 
     certificateGenerator.SetSerialNumber(serialNumber); 

     // Signature Algorithm 
     const string signatureAlgorithm = "SHA256WithRSA"; 
     certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm); 

     // Issuer and Subject Name 
     X509Name subjectDN = new X509Name(subjectName); 
     X509Name issuerDN = new X509Name(issuerName); 
     certificateGenerator.SetIssuerDN(issuerDN); 
     certificateGenerator.SetSubjectDN(subjectDN); 

     // Valid For 
     DateTime notBefore = DateTime.UtcNow.Date; 
     DateTime notAfter = notBefore.AddYears(2); 

     certificateGenerator.SetNotBefore(notBefore); 
     certificateGenerator.SetNotAfter(notAfter); 

     // Subject Public Key 
     AsymmetricCipherKeyPair subjectKeyPair; 
     var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength); 
     var keyPairGenerator = new RsaKeyPairGenerator(); 
     keyPairGenerator.Init(keyGenerationParameters); 
     subjectKeyPair = keyPairGenerator.GenerateKeyPair(); 

     certificateGenerator.SetPublicKey(subjectKeyPair.Public); 

     // Generating the Certificate 
     AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair; 

     // selfsign certificate 
     Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(subjectKeyPair.Private, random); 

     // correcponding private key 
     PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private); 

     // merge into X509Certificate2 
     X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded()); 


     Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(info.PrivateKey.GetDerEncoded()); 
     if (seq.Count != 9) 
     { 
      //throw new PemException("malformed sequence in RSA private key"); 
     } 

     RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq); 
     RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
      rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient); 

     x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams); 
     // Console.Write("Private key: " + x509.PrivateKey); 
     return x509; 

} 
+0

X509KeyStorageFlags.Exportable https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509keystorageflags(v=vs.110).aspx – MMK

+0

Vâng tôi biết nó ở đó, bạn chỉ sử dụng nếu bạn muốn đặt khóa bí mật thành có thể xuất. Không phải hướng ngược lại. Như bạn có thể thấy tôi đã không sử dụng nó. – Spyral

+0

mọi thứ chỉ dựa trên phần mềm dễ dàng trích xuất, ngay cả khi nó không thể xuất được, bạn chỉ có thể đợi chương trình của bạn sử dụng nó, và sau đó memorydump nó, hoặc bất cứ điều gì. Theo kinh nghiệm của tôi, nếu bạn muốn ở bên an toàn, hãy sử dụng một cái gì đó như codemeter cộng với codeencryption/obfuscation. Nó không phải bất khả xâm phạm, nhưng trong hầu hết mọi trường hợp không đáng để nỗ lực. –

Trả lời

3

DotNetUtilities.ToRSA sẽ luôn đặt khóa riêng thành Có thể xuất. Để ngăn chặn điều này, có một cách khác để chuyển đổi quan trọng BouncyCastle của bạn đến một NET X509Certificate2 như lấy from here

public X509Certificate2 GenerateSelfSignedCertificateNoCA(string subjectName, string issuerName) 
    { 
     const int keyStrength = 2048; 

     // Generating Random Numbers 
     CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator(); 
     SecureRandom random = new SecureRandom(randomGenerator); 

     // The Certificate Generator 
     X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator(); 

     // Serial Number 
     BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); 
     certificateGenerator.SetSerialNumber(serialNumber); 

     // Signature Algorithm 
     const string signatureAlgorithm = "SHA256WithRSA"; 
     certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm); 

     // Issuer and Subject Name 
     X509Name subjectDN = new X509Name(subjectName); 
     X509Name issuerDN = new X509Name(issuerName); 
     certificateGenerator.SetIssuerDN(issuerDN); 
     certificateGenerator.SetSubjectDN(subjectDN); 

     // Valid For 
     DateTime notBefore = DateTime.UtcNow.Date; 
     DateTime notAfter = notBefore.AddYears(2); 

     certificateGenerator.SetNotBefore(notBefore); 
     certificateGenerator.SetNotAfter(notAfter); 

     // Subject Public Key 
     AsymmetricCipherKeyPair subjectKeyPair; 
     var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength); 
     var keyPairGenerator = new RsaKeyPairGenerator(); 
     keyPairGenerator.Init(keyGenerationParameters); 
     subjectKeyPair = keyPairGenerator.GenerateKeyPair(); 

     certificateGenerator.SetPublicKey(subjectKeyPair.Public); 

     // Generating the Certificate 
     AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair; 

     // selfsign certificate 
     Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(subjectKeyPair.Private, random); 

     //import into store 
     var certificateEntry = new X509CertificateEntry(certificate); 
     string friendlyName = certificate.SubjectDN.ToString(); 
     var store = new Pkcs12Store(); 
     store.SetCertificateEntry(friendlyName, certificateEntry); 
     store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(subjectKeyPair.Private), new[] {certificateEntry}); 

     //save to memorystream 
     var password = "password"; 
     var stream = new MemoryStream(); 
     store.Save(stream, password.ToCharArray(), random); 

     // convert into X509Certificate2 
     X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(stream.ToArray(), password, X509KeyStorageFlags.UserKeySet); 

     return x509; 
    } 

Chìa khóa tư nhân hiện nay được đánh dấu là có thể xuất khẩu = false.

2

này là không thể với pkcs12/PFX.

Bạn không nên bỏ qua khóa cá nhân không thể xuất được dưới dạng dự phòng bảo mật "không thể phá vỡ" hoặc "khó giải quyết". Có những tiện ích sẽ xuất một khóa riêng không thể xuất được.

Nếu bạn cần bảo vệ khóa riêng tư, tôi khuyên bạn nên sử dụng mã thông báo mã hóa/thẻ thông minh hoặc mô-đun bảo mật phần cứng.

Các vấn đề liên quan