C# certutil.exe返回“;指定的网络密码不正确";

C# certutil.exe返回“;指定的网络密码不正确";,c#,x509certificate,bouncycastle,self-signed,certutil,C#,X509certificate,Bouncycastle,Self Signed,Certutil,我正在使用Bouncy Castle库创建CA根证书和自签名机器证书,如下所示。我在下面列出了整个实现。我能够创建受密码保护的.PFX文件 尽管我创建了CA根证书,但我没有安装它,因为它已经安装在计算机上(具有相同的主题和颁发者)。此外,我不确定原始的汽车根证书(MyCARoot.cer)是如何创建的,但它是通过以下命令安装的: certmgr.exe/add MyCARoot.cer/c/s/r localMachine root 在某些时候,我能够安装使用certutil.exe创建的自签名

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

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

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

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

  • 我在这里的问题针对一个或多个领域:

    • 我下面的实现是否正确-我是否遗漏了“允许私钥导出”或类似的内容
    • 无论整个方法是否正确-我切换到它,因为我需要手动创建和安装自签名机器证书,而不是使用makecert.exe和pvk2pfx.exe,其中会提示用户4次输入私钥密码
    • 如何验证生成的.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.");
          }
      
  • 功能和实现:

           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;
        }
    
    public static X509Certificate2 GenerateSelfSignedCertificate(字符串subjectName、字符串issuerName、AsymmetricKeyParameter issuerPrivKey、int-keyStrength=4096)
    {
    使用(Log.VerboseCall())
    {
    尝试
    {
    //生成随机数
    var randomGenerator=新的CryptoApiranomGenerator();
    var random=新的SecureRandom(随机生成器);
    详细(“生成的随机数”);
    ISignatureFactory signatureFactory=新的ASN1 signatureFactory(“SHA512 with RSA”,issuerPrivKey,随机);
    详细(“生成的SignatureFactory”);
    //证书生成器
    var certificateGenerator=新X509V3CertificateGenerator();
    certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id,true,新的ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth));
    //序列号
    var serialNumber=bigingers.CreateRandomInRange(biginger.One,biginger.ValueOf(Int64.MaxValue),random);
    证书生成器。设置序列号(序列号);
    详细(“将序列号添加到CertificateGenerator”);
    //发行人和主题名称
    X509Name subjectDN=新的X509Name(“CN=“+subjectName”);
    X509Name issuerDN=新的X509Name(“CN=“+issuerName”);
    certificateGenerator.SetIssuerDN(发行人N);
    certificateGenerator.SetSubjectDN(subjectDN);
    详细(“已设置主题名称和发行人名称”);
    //适用于
    var notBefore=DateTime.UtcNow.Date;
    var notAfter=notBefore.AddYears(100);
    证书生成器。SetNotBefore(notBefore);
    证书生成器。SetNotAfter(notAfter);
    //主题公钥
    非对称密码密钥对主体密钥对;
    var keyGenerationParameters=新的keyGenerationParameters(随机、keyStrength);
    var keyPairGenerator=new rsakypairgenerator();
    keyPairGenerator.Init(keyGenerationParameters);
    subjectKeyPair=keyPairGenerator.GenerateKeyPair();
    certificateGenerator.SetPublicKey(subjectKeyPair.Public);
    Verbose(“已生成并设置主题公钥”);
    //生成证书
    var issuerKeyPair=主题密钥对;
    //注#1
    //在另一篇参考文章中,我看到了这一点——相反
    //var dotNetPrivateKey=ToDotNetKey(privateKey);
    //var dotNetCert=newx509certificate2(DotNetUtilities.ToX509Certificate(newCert));
    //dotNetCert.PrivateKey=dotNetPrivateKey;
    //自签名证书
    var certificate=certificateGenerator.Generate(signatureFactory);
    var dotNetPrivateKey=ToDotNetKey((RsaPrivateCrtKeyParameters)subjectKeyPair.Private);
    详细日志(“生成的证书”);
    //相应的私钥
    PrivateKeyInfo=PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);
    详细(“创建的私钥”);
    //合并到X509Certificate2中
    var x509=new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());
    详细(“生成的编码证书”);
    var seq=(Asn1Sequence)Asn1Object.FromByteArray(info.ParsePrivateKey().getDeRecoded());
    如果(序号!=9)
    抛出新的异常(“RSA私钥中的错误序列”);
    RsaPrivateKeyStructure rsa=RsaPrivateKeyStructure.GetInstance(seq);
    RsaPrivateCrtKeyParameters rsaparms=新的RsaPrivateCrtKeyParameters(rsa.modules,rsa.PublicExponent,
    rsa.PrivateExponent,rsa.Prime1,
    rsa.Prime2,rsa.Exponent1,
    rsa.指数2,rsa.系数);
    Verbose(“生成的RSA密钥参数”);
    x509.PrivateKey=DotNetUtilities.ToRSA(rsaparms);
    Verbose(“已设置CA私钥”);
    返回x50