使用它之前是否必须在密钥库中安装PKCS12 / PFX证书?

时间:2018-09-15 21:57:59

标签: c# windows ssl x509 pfx

在C#的http客户端应用程序中使用客户端证书时遇到问题。客户端证书在运行时由服务器作为X509Certificate交付。我也有私钥。因此,我生成了PKCS12 / PFX对象(X509Certificate2)。现在,当我在多线程环境中运行该应用程序时,在每个线程中,每个线程都使用从服务器接收到的不同客户端证书来创建新的SSL连接,随机地,某些SSL握手失败并且通过了。网络跟踪显示客户端发送客户端证书后SSL握手失败。

请注意,我尚未将X509Certificate2存储在商店中。如果我不使用客户端证书,则一切正常(服务器发送401,因为它需要客户端证书,但SSL握手永远不会失败)。

是因为我没有在商店中安装客户端证书X509Certificate2对象吗?是否必须在商店中安装PKCS12证书?

这是SSL握手的方法:

        public void SslHandshake(ConnectionParams connectionParams)
        {
            TcpClient mClient = new TcpClient(connectionParams.HostFqdn, connectionParams.Port);
            SslStream mSslStream = new SslStream(mClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
            try
            {
                if (connectionParams.ClientCertificate != null)
                {
                    mSslStream.AuthenticateAsClient(connectionParams.HostFqdn, new X509Certificate2Collection(connectionParams.ClientCertificate), SslProtocols.Tls12, false);
                }
                else
                {
                    mSslStream.AuthenticateAsClient(connectionParams.HostFqdn);
                }
            }
            catch (AuthenticationException e)
            {
                sLog.Error("Exception establishing SSL connection: " + e.Message);
                if (e.InnerException != null)
                {
                    sLog.Error("Inner exception establishing SSL connection: " + e.InnerException.Message);
                }
                mSslStream.Close();
                mClient.Close();
                throw new ApiException("SSL handshake failed - closing the connection.");
            }
        }

======= EDIT ======

这是使用充气桥X509Certficate和私钥生成DotNet X509Certificate2对象的方法。

public System.Security.Cryptography.X509Certificates.X509Certificate2 CreatePkcs12(X509Certificate bcCert, AsymmetricKeyParameter privateKey)
        {
            var x509Certificate = DotNetUtilities.ToX509Certificate(bcCert);
            var certBytes = x509Certificate.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs12, IosHelper.DEVICE_CERT_PFX_PASSWORD);
            var certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(certBytes, IosHelper.DEVICE_CERT_PFX_PASSWORD, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.PersistKeySet | System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.MachineKeySet);
            if(privateKey != null)
            {
                var rsaParams = DotNetUtilities.ToRSAParameters(privateKey as RsaPrivateCrtKeyParameters);
                var cspParams = new CspParameters();
                cspParams.KeyContainerName = "KeyContainer";
                var rsaPrivate = new RSACryptoServiceProvider(cspParams);
                rsaPrivate.ImportParameters(rsaParams);
                certificate.PrivateKey = rsaPrivate;
            }
            return certificate;
        }

0 个答案:

没有答案