gpt4 book ai didi

.net - 为什么我的客户端证书没有包含在 TLS 握手中?

转载 作者:行者123 更新时间:2023-12-01 15:51:49 26 4
gpt4 key购买 nike

几年前我编写了一个 Windows 服务来处理来自多个来源的数据,其中一个是第三方 SOAP Web 服务。它使用第三方提供的客户端证书通过此 Web 服务进行身份验证。这在当时运行良好,并且在部署它的原始机器上仍然运行良好,但现在他们正在迁移到一台新机器,连接尝试抛出异常并显示消息:

The HTTP request was forbidden with client authentication scheme 'Anonymous'

同样的事情现在也发生在我的开发机器上。这是配置与 Web 服务的连接的代码:

Friend Shared Function GetProperlyConfiguredConnection() As SEMOService.MIWebServiceClient
' Ensure that the settings are valid
ValidateSettings()

Dim destAddress As New System.ServiceModel.EndpointAddress(Url)
' The service uses SOAP 1.1 which is what BasicHttpBinding uses. WSHttpBinding uses SOAP 1.2.
'Dim destBinding As New System.ServiceModel.WSHttpBinding
Dim destBinding As New System.ServiceModel.BasicHttpBinding
With destBinding
.CloseTimeout = New TimeSpan(0, 1, 0)
.OpenTimeout = New TimeSpan(0, 1, 0)
.ReceiveTimeout = New TimeSpan(0, 10, 0)
.SendTimeout = New TimeSpan(0, 1, 0)
.BypassProxyOnLocal = False
.HostNameComparisonMode = ServiceModel.HostNameComparisonMode.StrongWildcard
.MaxBufferPoolSize = 524288
.MaxReceivedMessageSize = 2147483647
.MessageEncoding = ServiceModel.WSMessageEncoding.Text
.TextEncoding = System.Text.Encoding.UTF8
.UseDefaultWebProxy = True
.AllowCookies = False

With .ReaderQuotas
.MaxDepth = 32
.MaxStringContentLength = 2147483647
.MaxArrayLength = 50000000
.MaxBytesPerRead = 4096
.MaxNameTableCharCount = 16384
End With

.Security.Mode = ServiceModel.BasicHttpSecurityMode.Transport
.Security.Transport.ClientCredentialType = ServiceModel.HttpClientCredentialType.Certificate
End With

Dim wcfService As New SEMOService.MIWebServiceClient(destBinding, destAddress)

' Load the certificate from the specified file.
Dim keyData As Byte()
Dim keyFileInfo As New IO.FileInfo(SEMOServiceSettings.KeyFilePath)
Dim keyFileReader As New IO.BinaryReader(New IO.FileStream(SEMOServiceSettings.KeyFilePath, IO.FileMode.Open, IO.FileAccess.Read))
keyData = keyFileReader.ReadBytes(keyFileInfo.Length)
keyFileReader.Close()

Dim cert As New X509Certificates.X509Certificate2
cert = New X509Certificates.X509Certificate2(keyData, SEMOServiceSettings.KeyFilePassword)

wcfService.ClientCredentials.ClientCertificate.Certificate = cert

Return wcfService
End Function

它实际上不是 WCF Web 服务,但 Visual Studio 从 WSDL 自动生成客户端代码时似乎并不介意。客户端证书是从文件而不是证书存储中加载的。所有机器上都在使用相同的证书文件,并且在单步执行代码时似乎加载正常。

我使用 WireShark 比较了从工作机器发出的请求和从我的开发机器发出的请求,看起来客户端证书没有包含在应该包含的握手中:

No client certificates

这是工作机器上请求的相应数据包:

Full certificate chain

关于 WCF、SOAP 和密码学,我有很多不明白的地方,所以对于导致这种行为的环境可能有何不同,以及需要进行哪些更改以纠正,我有点不知所措

This question似乎是相关的,但我似乎无法通过代码访问任何 RequireClientCertificate 属性,并且我没有使用 app.config 来配置绑定(bind)。

可以向 ServicePointManager 类添加回调以执行服务器证书的自定义验证。在将客户端证书发送到服务器之前,客户端基类或绑定(bind)是否对客户端证书执行某些验证?如果是这样,有没有一种方法可以像服务器证书验证一样干预该过程,以便我可以看到发生了什么?

最佳答案

我找到了解决方案,但不确定我是否完全理解它。问题是客户端证书(或者可能只是链中的一些其他证书)需要出现在发出请求的用户的个人证书存储中。我以运行 Windows 服务的用户身份登录,将证书导入其存储区,现在一切正常。

这表明客户端证书以某种方式得到验证,即使它们是从文件加载而不是在商店中引用的。这实际上在 ProcMon 的输出中很明显,如果我更注意的话,我会意识到它正在搜索证书存储并得出 NOT FOUND 结果。

如果 Microsoft 的 WCF 客户端代码在证书有问题时抛出异常,而不是仅仅尝试在没有证书的情况下继续运行,那就太好了。嗯……

关于.net - 为什么我的客户端证书没有包含在 TLS 握手中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13125367/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com