我正在开发一个ASP.NET Web应用程序,使用HttpWebRequest向另一个服务器发送请求。它通过HTTPS发送请求,并且远程服务器需要客户端证书。在.NET应用程序中,请求失败,显然无法发送正确的客户端证书。如果我只是使用Web浏览器(特别是Chrome)访问URL,我就可以成功连接并发送客户端证书。
下面的代码是一个简单的重现,只包含基本的GET请求。
var r = WebRequest.Create(url) as HttpWebRequest;
r.ClientCertificates = new X509CertificateCollection { myX509Cert };
using (var resp = r.GetResponse() as HttpWebResponse) {
...
}
我遇到了我们最常见的异常“Could not create SSL/TLS secure channel”。通常,这些问题指向证书私钥权限的问题。我已经尝试了一切我能想到的来确保证书配置正确,但可能我漏掉了什么。简而言之,远程服务器正在发送带有列表的TLS CertificateRequest
,但我的应用程序无法响应任何客户端证书。这是我的设置:
· Windows 7 Professional 64位 · 可以在运行于Visual Studio开发服务器的ASP.NET MVC 3 / .NET 4应用程序中再现该问题,在本地IIS运行的ASP.NET WebForms / .NET 3.5应用程序和.NET控制台应用程序/ .NET 4中也可以再现该问题。 · 最近安装了Microsoft .NET Framework 4.5。尚未检查是否可能存在问题
这里是我尝试过的所有方法以及我所知道的:
· 当在Windows XP机器上运行时,此代码似乎运行良好 · 确保将客户端证书导入本地计算机、个人证书存储区,并为自己和所有相关的IIS用户正确配置了私钥权限 · 尝试多次重新安装证书 · 已确认.NET应用程序可以访问X509证书,并且
HasPrivateKey
= true
· 确保客户端证书有效。实际上,它是用于运行此应用程序的Web服务器的SSL证书
· 在请求对象中设置PreAuthenticate = true
。没有任何区别
· 尝试设置ServicePointManager.Expect100Continue = false
,没有任何区别
· 尝试设置ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
,但显然远程服务器需要TLS,所以这并没有帮助
· 将ServicePointManager.ServerCertificateValidationCallback
委托设置为始终返回true。但是,在TLS握手之前,请求会在更早的阶段失败,甚至还没有到调用此委托的地步
· 当我在Chrome中访问该URL时,它要求我提供客户端证书,呈现正确的客户端证书作为选择,我选择该证书并获得有效响应。在Fiddler中构建请求时也可以正常工作。因此,它明显是具体问题出现在我的.NET代码中,而不是证书本身、远程服务器等等。
· 我正在使用的供应商在另一个远程服务器上设置了相同的服务,并且该服务需要不同的客户端证书。因此,我尝试了不同的URL和客户端证书,但仍然失败。我添加了System.Net跟踪并看到了这个:
SecureChannel#26717201 - 我们提供了用户证书。服务器已指定6个颁发者。寻找与任何发行人匹配的证书。 SecureChannel#26717201 - 没有客户端证书可供选择。
我启用了完整的SCHANNEL日志记录,看到了这个警告:
远程服务器请求SSL客户端身份验证,但找不到合适的客户端证书。将尝试匿名连接。此SSL连接请求可能会成功或失败,这取决于服务器的策略设置。
我运