certutil.exe возвращает "Указан неверный сетевой пароль"

  1. Я создаю корневой сертификат CA, а затем самоподписанный машинный сертификат, используя библиотеку Bouncy Castle следующим образом. Я перечислю ниже всю реализацию. Я могу создать защищенный паролем файл.PFX.

  2. Несмотря на то, что я создаю CA Root Certificate, я не устанавливаю его, потому что он уже установлен на машине (с тем же субъектом и издателем). Кроме того, я не уверен, как был создан оригинальный корневой сертификат CAR (MyCARoot.cer), но он устанавливается командой:

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

  3. В какой-то момент мне удалось установить самоподписанный сертификат компьютера (.PFX), который я создал с помощью certutil.exe, однако теперь он всегда возвращает вышеуказанную ошибку.

  4. Мой вопрос здесь касается одной или нескольких областей:

    • Является ли моя реализация ниже правильной - я пропустил что-то вроде "разрешения экспорта закрытого ключа" или подобное...
    • Правильный ли весь подход - я переключился на него, поскольку мне нужно было создать и установить сертификат самоподписанного компьютера, а не использовать 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;
    }

0 ответов

Другие вопросы по тегам