certutil.exe返回“指定的网络密码不正确”

时间:2017-08-02 19:24:08

标签: c# x509certificate bouncycastle self-signed certutil

  1. 我正在使用Bouncy Castle库创建CA Root Certificate然后使用自签名机器证书,如下所示。我在下面列出了整个实现。我能够创建受密码保护的.PFX文件。

  2. 尽管我创建了CA根证书,但我没有安装它,因为它已经安装在计算机上(具有相同的主题和颁发者)。除此之外,我不确定原始的CAR根证书(MyCARoot.cer)是如何创建的,但它是由命令安装的:

    certmgr.exe / add MyCARoot.cer / c / s / r localMachine root

  3. 在某些时候我能够安装我使用certutil.exe创建的自签名机器证书(.PFX),但现在它总是返回上述错误。

  4. 我的问题主要针对一个或多个领域:

    • 我的下面的实现是否正确 - 我是否错过了“允许私钥导出”或类似的内容......
    • 整个方法是否正确 - 我切换到它,因为我需要创建和安装自签名机器证书而不是使用makecert.exe和pvk2pfx.exe,其中用户被提示4次输入Private密码密码......
    • 如何验证我生成的.pfx是否正确? (除了尝试使用certutil.exe安装它?

              AsymmetricKeyParameter caPrivateKey = null;
      
          try
          {
              // Create Root CA certificate
              X509Certificate2 x509 = CertMaker.GenerateCACertificate(mSubject, ref caPrivateKey);
      
              // Save certificate to file
              byte[] certBytes = x509.Export(X509ContentType.Cert, mRootCaPwd);
              string certFilePath = Path.Combine(mInstallPath, mSubject + ".cer");
              File.WriteAllBytes(certFilePath, certBytes);
          }
          catch(Exception ex)
          {
              Log.Verbose(ex);
              TextLog.Info("Failed to generate CA Root Certificate");
              return;
          }
      
          if (caPrivateKey == null)
          {
              Log.Verbose("Failed to generate CA Root Certificate: Failed to generate private key.");
              TextLog.Info("Failed to generate CA Root Certificate: Failed to generate private key.");
              return;
          }
          try
          {
              X509Certificate2 cert = CertMaker.GenerateSelfSignedCertificate(mSubject, mIssuer, caPrivateKey);
      
              // Save certificate to file
              byte[] certBytes = cert.Export(X509ContentType.Pkcs12, mComputerCertPwd);
              string filename = String.Format("MyServer_{0}.pfx", mSubject);
              string certFilePath = Path.Combine(mInstallPath, filename);
              File.WriteAllBytes(certFilePath, certBytes);
          }
          catch(Exception ex)
          {
              Log.Verbose("Failed to generate Machine Certificate." + ex.Message);
              TextLog.Info("Failed to generate Machine Certificate.");
          }
      
  5. 和函数实现:

           public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey, int keyStrength = 4096)
        {
            using (Log.VerboseCall())
            {
                try
                {
                    // Generating Random Numbers
                    var randomGenerator = new CryptoApiRandomGenerator();
                    var random = new SecureRandom(randomGenerator);
                    Log.Verbose("Generated Random Numbers");
    
                    ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerPrivKey, random);
                    Log.Verbose("Generated SignatureFactory");
    
                    // The Certificate Generator
                    var certificateGenerator = new X509V3CertificateGenerator();
                    certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth));
    
                    // Serial Number
                    var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
                    certificateGenerator.SetSerialNumber(serialNumber);
    
                    Log.Verbose("Added Serial Number to CertificateGenerator");
    
                    // Issuer and Subject Name
                    X509Name subjectDN = new X509Name("CN=" + subjectName);
                    X509Name issuerDN = new X509Name("CN=" + issuerName);
                    certificateGenerator.SetIssuerDN(issuerDN);
                    certificateGenerator.SetSubjectDN(subjectDN);
    
                    Log.Verbose("Had set Subject Name and Issuer Name");
    
                    // Valid For
                    var notBefore = DateTime.UtcNow.Date;
                    var notAfter = notBefore.AddYears(100);
    
                    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);
    
                    Log.Verbose("Had generated and set Subject Public Key");
    
                    // Generating the Certificate
                    var issuerKeyPair = subjectKeyPair;
    
                    // NOTE #1
                    // In another reference I saw this - instead
                    //var dotNetPrivateKey = ToDotNetKey(privateKey);
                    //var dotNetCert = new X509Certificate2(DotNetUtilities.ToX509Certificate(newCert));
                    //dotNetCert.PrivateKey = dotNetPrivateKey;
    
                    // self-signed certificate
                    var certificate = certificateGenerator.Generate(signatureFactory);
                    var dotNetPrivateKey = ToDotNetKey((RsaPrivateCrtKeyParameters)subjectKeyPair.Private);
    
                    Log.Verbose("Generated Certificate");
    
                    // correcponding private key
                    PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);
    
                    Log.Verbose("Created Private Key");
    
                    // merge into X509Certificate2
                    var x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());
    
                    Log.Verbose("Generated Encoded Certificate");
    
                    var 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);
                    RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(rsa.Modulus, rsa.PublicExponent,
                                                                                          rsa.PrivateExponent, rsa.Prime1,
                                                                                          rsa.Prime2, rsa.Exponent1,
                                                                                          rsa.Exponent2, rsa.Coefficient);
    
                    Log.Verbose("Generated RSA Key Parameters");
    
                    x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
                    Log.Verbose("Had set CA Private Key");
    
                    return x509;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Failed to create Self-Signed Machine certificate: {0}", ex.Message);
                    return null;
                }
            }
        }
    
        /// <summary>
        /// Generate Self-Signed Root CA Certificate
        /// </summary>
        /// <param name="subjectName"></param>
        /// <param name="CaPrivateKey"></param>
        /// <returns>Returns the X509 certificate and reference to Root CA Private Key</returns>
        public static X509Certificate2 GenerateCACertificate(string subjectName, ref AsymmetricKeyParameter CaPrivateKey)
        {
            using (Log.VerboseCall())
            {
                try
                {
                    int keyStrength = 4096;
    
                    // Generating Random Numbers
                    CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
                    SecureRandom random = new SecureRandom(randomGenerator);
    
                    Log.Verbose("Generated Random Numbers");
    
                    // The Certificate Generator
                    X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
    
                    // Serial Number
                    BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
                    certificateGenerator.SetSerialNumber(serialNumber);
    
                    Log.Verbose("Added Serial Number to CertificateGenerator");
    
                    // Issuer and Subject Name
                    X509Name subjectDN = new X509Name("CN="+subjectName);
                    X509Name issuerDN = subjectDN;
                    certificateGenerator.SetIssuerDN(issuerDN);
                    certificateGenerator.SetSubjectDN(subjectDN);
    
                    Log.Verbose("Had set Subject Name and Issuer Name");
    
                    // Valid For
                    var notBefore = DateTime.UtcNow.Date;
                    var notAfter = notBefore.AddYears(100);
    
                    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);
    
                    Log.Verbose("Had generated and set Subject Public Key");
    
                    // Generating the Certificate
                    AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;
                    ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerKeyPair.Private, random);
    
                    Log.Verbose("Created SignatureFactory");
    
                    // selfsign certificate
                    // certificateGenerator.Generate signs the certificate using the private key, 
                    // but doesn't put the private key in the certificate, which wouldn't make sense.
                    Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory);
                    X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());
    
                    Log.Verbose("Generated CA Root Certificate");
    
                    CaPrivateKey = issuerKeyPair.Private;
    
                    Log.Verbose("Had set CA Private Key");
    
                    return x509;
                }
                catch (Exception ex)
                {
                    Log.VerboseFormat("Failed to create Root CA certificate: {0}", ex.Message);
                    return null;
                }
            }
        }
    
        /// <summary>
        /// See NOTE #1
        /// </summary>
        /// <param name="privateKey"></param>
        /// <returns></returns>
        public static AsymmetricAlgorithm ToDotNetKey(RsaPrivateCrtKeyParameters privateKey)
        {
            // If you don't do this (cspParams), when you execute the netsh command you get the error 1312. i.e. of the netsh command:
            //
            // netsh http add sslcert ipport = 192.168.0.15:8081 certhash =‎5424476237fc2785ed2d0fd620a9131d7c999f6f appid = { 02639d71 - 0935 - 35e8 - 9d1b - 9dd1a2a34627 }
    
            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 个答案:

没有答案