2016-12-22 24 views
9

私のコードでは、そこに秘密鍵を持つ自己署名証明書が作成されています。これはユーザーストアに保存されています。今私はmmcツールを使用して私は証明書から秘密鍵をエクスポートすることができますか?私はあなたが証明書を作成するときに明示的に追加しなければならないフラグだと思ったのですか?証明書の秘密鍵をエクスポートできないようにするにはC#

私が知りたいのは、このコードを変更して秘密鍵がもはやmmcからエクスポートできないようにする方法です。

コード:

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

はい、私はあなただけを使用、それはあります知っています明示的にprivキーをエクスポート可能に設定したい場合は、その逆ではありません。ご覧のとおり、私はそれを使用していません。 – Spyral

+0

ソフトウェアにのみ依存するものは、エクスポートできない場合でも簡単に抽出できます。プログラムが使用するのを待ってから、メモリダンプなどを実行することができます。私の経験上、あなたが安全な側にいたいなら、codemeterとcodeencryption/obfuscationのようなものを使用してください。それはunhackableではなく、ほとんどの場合、努力に値するものではありません。 –

答えて

3

DotNetUtilities.ToRSAは、常に秘密鍵をエクスポート可能に設定します。これを防ぐために、秘密鍵は今偽エクスポート可能=とマークされている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; 
    } 

取らとして.NET X509Certificate2にあなたはBouncyCastleキーを変換する別の方法があります。

2

これは、PKCS12/PFXでは不可能です。

エクスポートできない秘密鍵は、「破損しない」または「破損しにくい」セキュリティ対策として使用しないでください。非エクスポート可能な秘密鍵もエクスポートするユーティリティがあります。

秘密鍵を保護する必要がある場合は、暗号トークン/スマートカードまたはハードウェアセキュリティモジュールを使用することをお勧めします。

関連する問題