2016-04-19 19 views
9

自己署名入りの信頼できる証明書を作成しようとしています。私はヌーゲットのバウンシーキャッスルと答えはthis questionです。Bouncy CastleのX509V3CertificateGenerator.SetSignatureAlgorithmは時代遅れです。私は何をしますか?

public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey, int keyStrength = 2048) 
{ 
// Generating Random Numbers 
var randomGenerator = new CryptoApiRandomGenerator(); 
var random = new SecureRandom(randomGenerator); 

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

// Serial Number 
var 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 
var subjectDN = new X509Name(subjectName); 
var issuerDN = issuerName; 
certificateGenerator.SetIssuerDN(issuerDN); 
certificateGenerator.SetSubjectDN(subjectDN); 

// Valid For 
var notBefore = DateTime.UtcNow.Date; 
var 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 
var issuerKeyPair = subjectKeyPair; 

// selfsign certificate 
var certificate = certificateGenerator.Generate(issuerPrivKey, random); 

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


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

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

var 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); 
return x509; 
} 


public static AsymmetricKeyParameter GenerateCACertificate(string subjectName, int keyStrength = 2048) 
{ 
// Generating Random Numbers 
var randomGenerator = new CryptoApiRandomGenerator(); 
var random = new SecureRandom(randomGenerator); 

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

// Serial Number 
var 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 
var subjectDN = new X509Name(subjectName); 
var issuerDN = subjectDN; 
certificateGenerator.SetIssuerDN(issuerDN); 
certificateGenerator.SetSubjectDN(subjectDN); 

// Valid For 
var notBefore = DateTime.UtcNow.Date; 
var 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 
var issuerKeyPair = subjectKeyPair; 

// selfsign certificate 
var certificate = certificateGenerator.Generate(issuerKeyPair.Private, random); 
var x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded()); 
// Add CA certificate to Root store 
addCertToStore(cert, StoreName.Root, StoreLocation.CurrentUser); 

return issuerKeyPair.Private; 
} 

これまでのところ、とても良い、しかし「SetSignatureAlgorithm」及び方法は、古いものとしてマークされている「生成」:これは、そのページ上のコードです。 Intellisenseは "ISignatureFactory"を使用することを提案しています。誰かが私を正しい方向に向けることができますか?

答えて

11
static void Main() 
{ 
    //Console.WriteLine(ExecuteCommand("netsh http delete sslcert ipport=0.0.0.0:4443")); 
    var applicationId = ((GuidAttribute)typeof(Program).Assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0]).Value; 
    var certSubjectName = "TEST"; 
    var sslCert = ExecuteCommand("netsh http show sslcert 0.0.0.0:4443"); 
    Console.WriteLine(); 

    if (sslCert.IndexOf(applicationId, StringComparison.OrdinalIgnoreCase) >= 0) 
    { 
     Console.WriteLine("This implies we can start running."); 
     Console.WriteLine(ExecuteCommand("netsh http delete sslcert ipport=0.0.0.0:4443")); 
     //store.Remove(certs.First(x => x.Subject.Contains(certSubjectName))); 
    } 

    AsymmetricKeyParameter myCAprivateKey = null; 
    Console.WriteLine("Creating CA"); 
    X509Certificate2 certificateAuthorityCertificate = CreateCertificateAuthorityCertificate("CN=" + certSubjectName + "CA", ref myCAprivateKey); 
    Console.WriteLine("Adding CA to Store"); 
    AddCertificateToSpecifiedStore(certificateAuthorityCertificate, StoreName.Root, StoreLocation.LocalMachine); 

    Console.WriteLine("Creating certificate based on CA"); 
    X509Certificate2 certificate = CreateSelfSignedCertificateBasedOnCertificateAuthorityPrivateKey("CN=" + certSubjectName, "CN=" + certSubjectName + "CA", myCAprivateKey); 
    Console.WriteLine("Adding certificate to Store"); 
    AddCertificateToSpecifiedStore(certificate, StoreName.My, StoreLocation.LocalMachine); 

    Console.WriteLine(ExecuteCommand($"netsh http add sslcert ipport=0.0.0.0:4443 certhash={certificate.Thumbprint} appid={{{applicationId}}}")); 

    // Check to see if our cert exists 
    // If the cert does not exist create it then bind it to the port 
    // If the cert does exist then check the port it is bound to 
    // If the port and thumbprint match and applicationId match continue 
    // Else throw exception 
    // See here for more netsh commands https://msdn.microsoft.com/en-us/library/ms733791(v=vs.110).aspx 
} 

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

    // Generating Random Numbers 
    CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator(); 
    SecureRandom random = new SecureRandom(randomGenerator); 
    ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerPrivKey, random); 
    // The Certificate Generator 
    X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator(); 
    certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage((new ArrayList() { new DerObjectIdentifier("1.3.6.1.5.5.7.3.1") }))); 

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

    // Signature Algorithm 
    //const string signatureAlgorithm = "SHA512WITHRSA"; 
    //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 
    X509Certificate certificate = certificateGenerator.Generate(signatureFactory); 

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


    // merge into X509Certificate2 
    X509Certificate2 x509 = new X509Certificate2(certificate.GetEncoded()); 

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

    RsaPrivateKeyStructure rsa = RsaPrivateKeyStructure.GetInstance(seq); //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); 
    return x509; 

} 
public static X509Certificate2 CreateCertificateAuthorityCertificate(string subjectName, ref AsymmetricKeyParameter CaPrivateKey) 
{ 
    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 = subjectDN; 
    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; 
    KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, keyStrength); 
    RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator(); 
    keyPairGenerator.Init(keyGenerationParameters); 
    subjectKeyPair = keyPairGenerator.GenerateKeyPair(); 

    certificateGenerator.SetPublicKey(subjectKeyPair.Public); 

    // Generating the Certificate 
    AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair; 
    ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerKeyPair.Private, random); 
    // selfsign certificate 
    X509Certificate certificate = certificateGenerator.Generate(signatureFactory); 
    X509Certificate2 x509 = new X509Certificate2(certificate.GetEncoded()); 

    CaPrivateKey = issuerKeyPair.Private; 

    return x509; 
    //return issuerKeyPair.Private; 

} 
public static bool AddCertificateToSpecifiedStore(X509Certificate2 cert, StoreName st, StoreLocation sl) 
{ 
    bool bRet = false; 

    try 
    { 
     X509Store store = new X509Store(st, sl); 
     store.Open(OpenFlags.ReadWrite); 
     store.Add(cert); 

     store.Close(); 
    } 
    catch 
    { 
     Console.WriteLine("An error occured"); 
    } 

    return bRet; 
} 
public static string ExecuteCommand(string action) 
{ 
    StringBuilder stringBuilder = new StringBuilder(); 
    using (Process process = new Process 
    { 
     StartInfo = new ProcessStartInfo 
     { 
      WindowStyle = ProcessWindowStyle.Normal, 
      FileName = "cmd.exe", 
      UseShellExecute = false, 
      RedirectStandardOutput = true, 
      Arguments = "/c " + action 
     } 
    }) 
    { 
     Console.WriteLine("Executing Command:"); 
     Console.WriteLine(action); 
     process.Start(); 
     while (!process.StandardOutput.EndOfStream) 
     { 
      stringBuilder.AppendLine(process.StandardOutput.ReadLine()); 
     } 
     process.Close(); 
    } 

    return stringBuilder.ToString(); 
} 

もっと完全な答えです。これにより、両方のメソッドで廃止されたコールがすべて取り除かれます。

注 - 私はNuGetのインストール・パッケージBouncyCastle.Crypto.dll

+0

ありがとう!確かに完全な答えです。ただし、X509V3CertificateGeneratorクラスのAddExtension()メソッドも古いものとしてマークされています。 IEnumerableを予期しているオーバーロードされたメソッドはありません。そこで、私はその行を次のように変更しました: 'certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage、true、new ExtendedKeyUsage(新しいList Lourens

+1

おっと、私はExtendedKeyUsage()コンストラクタを意味していました... – Lourens

+0

これを行うにはさらに良い方法があります。 certificateGenerator.AddExtension( X509Extensions.ExtendedKeyUsage.Id、 true、 新しいExtendedKeyUsage(KeyPurposeID.IdKPServerAuth)); – IdahoSixString

7

をIdahoSixStringの優れた答えは、より完全にするために使用していました: 上記のコードは、それがに証明書をバインドしようとする部分には動作しません。あなたがエラーを取得します

('netsh http add sslcert ipport=0.0.0.0:4443 certhash={certificate.Thumbprint} appid={{{applicationId}}}'). At least not in .NET4.5. 

:プログラムとポートは、秘密鍵は、nがないので

"SSL Certificate add failed, Error: 1312 A specified logon session does not exist. It may already have been terminated."

これは、明らかですotは、対応するRSAオブジェクトが閉じられたときに存続します。だから私はthis linkのアドバイスに従って、次のコードが私のために働く:

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

     // Generating Random Numbers 
     CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator(); 
     SecureRandom random = new SecureRandom(randomGenerator); 
     ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerPrivKey, random); 

     // The Certificate Generator 
     X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator(); 
     certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth)); 

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

     // Issuer and Subject Name 
     X509Name subjectDN = new X509Name("CN=" + subjectName); 
     X509Name issuerDN = new X509Name("CN=" + 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); 

     // selfsign certificate 
     Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory); 
     var dotNetPrivateKey = ToDotNetKey((RsaPrivateCrtKeyParameters)subjectKeyPair.Private); 

     // merge into X509Certificate2 
     X509Certificate2 x509 = new X509Certificate2(DotNetUtilities.ToX509Certificate(certificate)); 
     x509.PrivateKey = dotNetPrivateKey; 
     x509.FriendlyName = subjectName; 

     return x509; 
    } 

    public static X509Certificate2 CreateCertificateAuthorityCertificate(string subjectName, out AsymmetricKeyParameter CaPrivateKey) 
    { 
     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); 

     // Issuer and Subject Name 
     X509Name subjectDN = new X509Name("CN=" + subjectName); 
     X509Name issuerDN = subjectDN; 
     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; 
     KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, keyStrength); 
     RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator(); 
     keyPairGenerator.Init(keyGenerationParameters); 
     subjectKeyPair = keyPairGenerator.GenerateKeyPair(); 

     certificateGenerator.SetPublicKey(subjectKeyPair.Public); 

     // Generating the Certificate 
     AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair; 
     ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerKeyPair.Private, random); 

     // selfsign certificate 
     Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory); 

     X509Certificate2 x509 = new X509Certificate2(certificate.GetEncoded()); 
     x509.FriendlyName = subjectName; 

     CaPrivateKey = issuerKeyPair.Private; 

     return x509; 
    } 

    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); 
     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; 
    } 
+0

RSAオブジェクトがいつ、どのように閉じられるかはわかりますか? – IdahoSixString

+0

@ lourensあなたの完全なソリューションのおかげで、私は過去2日間、1312エラーで大げさになってしまいました...! – zukanta

+0

@lourens、ok、close、シガーなし...私は "localhost:4444 'という権限でSSL/TLSセキュアチャンネルの信頼関係を確立できませんでした。"この証明書を使用している私のサービスへのSSL接続をテストするときにあなたもそれを解決しましたか? (拡張キー使用プロパティも証明書mmcに警告の感嘆符が表示されます)。 – zukanta

関連する問題