c# – 使用HTTPClient进行双向身份验证

我正在尝试对需要双向SSL连接的服务器进行HTTP调用(客户端验证).我有一个包含多个证书和密码的.p12文件.请求使用协议缓冲区进行序列化.

我的第一个想法是将密钥库添加到HttpClient使用的WebRequestHandler的ClientCertificate属性中.我还将密钥库添加到我的电脑上的受信任的根证书颁发机构.

当PostAsync执行时,我总是得到“无法创建ssl / tls安全通道”.显然有些事情我错了,但我在这里有点失落.

任何指针都将不胜感激.

public void SendRequest()
    {
        try
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

            var handler = new WebRequestHandler();

            // Certificate is located in bin/debug folder
            var certificate = new X509Certificate2Collection();
            certificate.Import("MY_KEYSTORE.p12","PASSWORD",X509KeyStorageFlags.DefaultKeySet);

            handler.ClientCertificates.AddRange(certificate);
            handler.ServerCertificateValidationCallback = ValidateServerCertificate;

            var client = new HttpClient(handler)
            {
                BaseAddress = new Uri("SERVER_URL")
            };
            client.DefaultRequestHeaders.Add("Accept","application/x-protobuf");
            client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type","application/x-protobuf");
            client.Timeout = new TimeSpan(0,5,0);

            // Serialize protocol buffer payload
            byte[] protoRequest;
            using (var ms = new MemoryStream())
            {
                Serializer.Serialize(ms,MyPayloadobject());
                protoRequest = ms.ToArray();
            }

            var result = await client.PostAsync("/resource",new ByteArrayContent(protoRequest));

            if (!result.IsSuccessstatusCode)
            {
                var stringContent = result.Content.ReadAsstringAsync().Result;
                if (stringContent != null)
                {
                    Console.WriteLine("Request Content: " + stringContent);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            throw;
        }
   }

        private bool ValidateServerCertificate(object sender,X509Certificate certificate,X509Chain chain,SslPolicyErrors sslPolicyErrors)
        {
            if (sslPolicyErrors == SslPolicyErrors.None)
                return true;

            Console.WriteLine("Certificate error: {0}",sslPolicyErrors);

            // Do not allow this client to communicate with unauthenticated servers.
            return false;
        }

编辑

我甚至不打破ValidateServerCertificate.一旦调用了PostAsync,就会抛出异常.协议绝对是TLS v1.

客户端操作系统是Windows 8.1.服务器是用Java编码的(不知道它在运行什么操作系统,我没有访问权限,这是一个黑盒子)

堆栈跟踪

在System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult,TransportContext& context)
在System.Net.Http.httpclienthandler.GetRequestStreamCallback(IAsyncResult ar)

没有内在的例外.

解决方法

您尝试将安全协议更改为Ssl3吗?无论哪种情况,您都需要将Expect属性设置为true.它会修复你的错误.此外,您可以探索 this link获取更多关于通过客户端证书进行身份验证的知识.
public void SendRequest()
{
    try
    {
        ServicePointManager.Expect100Continue = true;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

        var handler = new WebRequestHandler();
        .....
    }
    ..
}

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...