c# - 使用客户端证书身份验证连接到 Web 服务

标签 c# client-certificates

我得到了一个 .p12 文件,用于使用客户端证书身份验证通过 SSL 连接到 Web 服务。我使用 cURL 在 PHP 中成功地工作了。这些是我在执行请求时使用的选项:

$headers = array(
    'Method: POST',
    'Connection: Keep-Alive',
    'User-Agent: PHP-SOAP-CURL',
    'Content-Type: text/xml; charset=utf-8',
    'SOAPAction: "'.$action.'"',
);

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $location);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_SSLCERT, $this->clientcert);
curl_setopt($ch, CURLOPT_SSLKEYTYPE, $this->clientcerttype);
curl_setopt($ch, CURLOPT_SSLKEY, $this->keyfile);
curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $this->keypassword);
curl_setopt($ch, CURLOPT_SSLVERSION, 3);

$response = curl_exec($ch);

我现在正尝试使用 C# 和 .NET 执行相同的任务,但我不断收到错误消息“无法使用权​​限‘:’为 SSL/TLS 建立安全通道。”。

我似乎没有找到 key 的问题,而且似乎没有任何信任问题。尽管如此,还是有些地方不对劲。

我已经制作了一个测试程序,这样我就可以测试一个基本的调用是否有效。

public void StartviaWSHttp()
{
    var binding = new WSHttpBinding();
    binding.Security.Mode = SecurityMode.Transport;
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
    binding.Security.Message.NegotiateServiceCredential = false;
    binding.Security.Message.ClientCredentialType = MessageCredentialType.None;

    var baseAddress = new Uri("https://<host>:<port>/LineEndpoint1");
    var endpointAddress = new EndpointAddress(baseAddress);

    var client = new LinePortTypeClient(binding, endpointAddress);

    client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySerialNumber, "00d48a233bf4b77523");

    Debug.Assert(client.ClientCredentials.ClientCertificate.Certificate.SerialNumber.ToLower() == "00d48a233bf4b77523");

    var header = new ctSoapHeaderMsg();
    var response = new object();
    client.Open();
    var responseCode = client.PerformFunction(ref header, "0893411111", out response);
    client.Close();

    Console.WriteLine("Response Code :" + responseCode);
    Console.WriteLine("Response :" + response);
}

当我在当前用户的个人/证书中查看证书时,它没有报告任何关于信任的问题。在证书信息中,写明该证书的用途如下:所有的颁发政策和所有的申请政策。证书路径只有一个条目,证书状态报告“此证书正常”。

我不知道问题是什么。可能存在信任问题,因为我为 PHP 调用关闭了 PEER 和 HOST 验证。我不确定这是否是 C# 的一个选项。


更新:(2013 年 8 月 9 日) 我为 System.Net 和 System.Net.Socket 设置了一些详细的跟踪。这是输出的开始。

System.Net Verbose: 0 : [16124] WebRequest::Create(https://dsl-wholesale-testing.iinet.net.au:50500/LineEndpoint1)
System.Net Verbose: 0 : [16124] HttpWebRequest#58508234::HttpWebRequest(https://dsl-wholesale-testing.iinet.net.au:50500/LineEndpoint1#128335743)
System.Net Information: 0 : [16124] Current OS installation type is 'Client'.
System.Net Information: 0 : [16124] RAS supported: True
System.Net Verbose: 0 : [16124] Exiting HttpWebRequest#58508234::HttpWebRequest() 
System.Net Verbose: 0 : [16124] Exiting WebRequest::Create()    -> HttpWebRequest#58508234
System.Net Verbose: 0 : [16124] ServicePoint#36898364::ServicePoint(dsl-wholesale-testing.iinet.net.au:50500)
System.Net Information: 0 : [16124] Associating HttpWebRequest#58508234 with ServicePoint#36898364
System.Net Verbose: 0 : [16124] HttpWebRequest#58508234::GetRequestStream()
System.Net Information: 0 : [16124] Associating Connection#47995487 with HttpWebRequest#58508234
System.Net.Sockets Verbose: 0 : [16124] Socket#31002555::Socket(AddressFamily#2)
System.Net.Sockets Verbose: 0 : [16124] Exiting Socket#31002555::Socket() 
System.Net.Sockets Verbose: 0 : [16124] Socket#6243847::Socket(AddressFamily#23)
System.Net.Sockets Verbose: 0 : [16124] Exiting Socket#6243847::Socket() 
System.Net.Sockets Verbose: 0 : [16124] DNS::TryInternalResolve(dsl-wholesale-testing.iinet.net.au)
System.Net.Sockets Verbose: 0 : [16124] Socket#31002555::Connect(203.173.51.130:50500#-2110560113)
System.Net.Sockets Information: 0 : [16124] Socket#31002555 - Created connection from 192.168.190.202:55397 to 203.173.51.130:50500.
System.Net.Sockets Verbose: 0 : [16124] Exiting Socket#31002555::Connect() 
System.Net.Sockets Verbose: 0 : [16124] Socket#6243847::Close()
System.Net.Sockets Verbose: 0 : [16124] Socket#6243847::Dispose()
System.Net.Sockets Verbose: 0 : [16124] Exiting Socket#6243847::Close() 
System.Net Information: 0 : [16124] Connection#47995487 - Created connection from 192.168.190.202:55397 to 203.173.51.130:50500.
System.Net Information: 0 : [16124] TlsStream#29695768::.ctor(host=dsl-wholesale-testing.iinet.net.au, #certs=0)
System.Net Information: 0 : [16124] Associating HttpWebRequest#58508234 with ConnectStream#25001628
System.Net Verbose: 0 : [16124] Exiting HttpWebRequest#58508234::GetRequestStream()     -> ConnectStream#25001628
System.Net Verbose: 0 : [16124] ConnectStream#25001628::Write()
System.Net Verbose: 0 : [16124] Data from ConnectStream#25001628::Write
System.Net Verbose: 0 : [16124] (printing 1024 out of 1206)
System.Net Verbose: 0 : [16124] 00000000 : 3C 73 3A 45 6E 76 65 6C-6F 70 65 20 78 6D 6C 6E : <s:Envelope xmln

System.Net Information: 0 : [16124] TlsStream#29695768::.ctor(host=dsl-wholesale-testing.iinet.net.au, #certs=0) 建议即使我已将证书附加到 client.ClientCredentials.ClientCertificate,也没有选择任何证书供使用,但我不确定为什么会发生这种情况或如何让它坚持下去。证书的任何属性是否必须与我要连接的主机名相匹配?

最佳答案

看来服务器不理解 TLS。

我必须指定 SSLv3,通过

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3;

关于c# - 使用客户端证书身份验证连接到 Web 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18049845/

相关文章:

google-chrome - Google Chrome 客户端证书弹出窗口

azure - Function-App 代理无法通过证书“X-ARR-ClientCert”传递到另一个 Function-App 的函数

ssl - 使用服务器端证书进行客户端身份验证

c# - 迭代 json 输入并基于 "keys"考虑到子级 "keys"创建类似 TreeView 的层次结构

c# - 使用按键触发 Blazor 中的按钮时未设置对象引用

c# - 什么首先执行 : ToggleButton. IsChecked 绑定(bind)更新,或命令绑定(bind)?

c# - 如何使用 Asp.Net WebAPI 进行路由?

node.js - 如何通过 Node 代理服务器的tls连接到远程tomcat

asp.net - 如何获得请求的数字签名(在双向 SSL 中)?

c# - 使用 C# 访问 OneDrive For Business (Office365) - 无法列出子文件夹