2016-04-19 53 views
9

Kendinden imzalı bir güvenilir sertifika oluşturmaya çalışıyorum. Bouncy Castle'ı nuget'ten kullanıyorum ve cevabı this question.Bouncy Castle'ın X509V3CertificateGenerator.SetSignatureAlgorithm eskiyle işaretlenmiş. Ben ne yaparım?

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; 
} 

Şu ana kadar çok iyi, ama "SetSignatureAlgorithm" ve yöntemler olarak eskimiş işaretlenir "Oluştur": Bu o sayfadaki koddur. Intellisense, bir "ISignatureFactory" kullanılmasını önerir ve burası kayboldum. Birisi bana doğru yönde işaret edebilir mi?

cevap

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(); 
} 

İşte daha eksiksiz bir yanıt. Bu, her iki yöntemdeki tüm eski çağrılardan kurtulur.

Not - Ben yükleyin-Paket BouncyCastle.Crypto.dll

+0

Teşekkürler! Bu tam bir cevaptır. Ancak, X509V3CertificateGenerator sınıfının AddExtension() yöntemi de geçersiz olarak işaretlenir. IEnumerable bekleyen aşırı yüklenmiş yöntem değildir. Bu satırı şu şekilde değiştirdim: 'certificateGenerator.AddExtension (X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage (yeni Liste Lourens

+1

Ayy, ExtendedKeyUsage() yapıcısını kastettim ... – Lourens

+0

İşte bunu yapmak için daha da iyi bir yöntem. certificateGenerator.AddExtension ( X509Extensions.ExtendedKeyUsage.Id, true, new ExtendedKeyUsage (KeyPurposeID.IdKPServerAuth)); – IdahoSixString

7

IdahoSixString mükemmel cevap rahat ettirmek için Nuget kullanıyordu: Yukarıdaki kod için sertifika bağlamaya çalıştığı kısmen işe yaramaz Sen hatası alırsınız

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

: Program ve bağlantı noktası özel anahtar n yapar çünkü

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

Bu görünüşe göre Karşılık gelen RSA nesnesi kapalı olduğunda devam eder. Bu nedenle this link numaralı telefondaki önerileri takip ettim ve şu kod benim için çalışıyor:

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 nesnesinin ne zaman ve nasıl kapandığını biliyor muyuz? – IdahoSixString

+0

@lourens COMPLETE çözümünüz için teşekkürler tomurcuk, son 2 gün boyunca 1312 hatası üzerinden kel oluyordum ...! – zukanta

+0

@lourens, tamam, yakın ama hiç puro ... "SSL/TLS güvenli kanalı için yetki" ile yerel sunucu: 4444 "güven ilişkisi kurulamadı." ssl bağlantısını bu sertifikayı kullanan servisime sınarken ... bunu da çözdünüz mü? (Ayrıca Gelişmiş Anahtar Kullanımı özelliği, sertifika mmc'de bir uyarı ünlem işareti ile gösterilir.) – zukanta