使用 TLS 1.2 的第三方 Soap Web 服务和使用 WCF 的客户端证书身份验证时出现 503 错误
503 error consuming thirdy part Soap webservice using TLS 1.2 and client certificate authentication with WCF
我在使用 Soap Web 服务(w/att.) 和需要客户端证书身份验证(相互?)的 MTOM 时遇到问题。
在写我已经尝试过的内容之前,我会向您展示我为获得客户证书所做的工作:
- 我用
openssl command openssl genrssa -out mykey.key 2048
生成了一个 RSA 密钥
- 我用这个密钥生成了一个 CSR:
openssl req -new -key mykey.key -out mycsr.csr
- 我已将此 CSR 发送给 Web 服务所有者以接收 客户端证书 ,他们给了我一个签名证书:certificate.cer
现在我已经获得了我的客户端证书,我已将它添加到我的证书存储区 Trusted Root Certification Authority.
下
现在代码:
首先,我在 Visual Studio 中创建了一个测试项目,并使用服务的 WSDL 添加了一个服务引用。
然后我写了几行代码:
' Setting TLS 1.2 protocol '
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
ServicePointManager.ServerCertificateValidationCallback = Function(sender1, certificate, chain, sslPolicyErrors)
Return True
End Function
'Creating endpoint and binding'
Dim endpoint As EndpointAddress = New EndpointAddress("https://myWebService.it/service-page")
Dim sslBinding As BasicHttpBinding = New BasicHttpBinding(BasicHttpSecurityMode.Transport)
'Setting CredentialType = Certificate'
sslBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate
'Getting the client certificate from the store'
Dim coll = New X509Store(StoreName.My, StoreLocation.CurrentUser)
coll.Open(OpenFlags.ReadOnly)
Dim cert = coll.Certificates.Find(X509FindType.FindByThumbprint, "76DB1454D4B25ACEAF2BAE465C310E3119278792", True)
'Creating the service'
Dim svc As SdITrasmissioneFileClient = New SdITrasmissioneFileClient(sslBinding, endpoint)
'Setting the certificate inside client credentials'
svc.ClientCredentials.ClientCertificate.Certificate = cert(0)
svc.Open()
'Calling the service'
Dim resp As RispostaEsito_Type = svc.Esito(New Esito_Type() With {.IDFile = "4454555"})
svc.Close()
它对我来说看起来很简单,但是当我执行我的代码时,我得到一个
System.ServiceModel.Security.MessageSecurityException: 'The HTTP
request was forbidden with client authentication scheme 'Anonymous'.'
Internal Exception: WebException: Remote Server Error: (403) Forbidden
接下来我使用 Fiddler 和 Wireshark 分析了流量,我发现在客户端和服务器之间的 TLS 握手期间,客户端不会将证书发送到服务器。
现在我不明白为什么,即使我将证书添加到客户端凭据,它也不会发送到目的地。
经过大量阅读,我发现了我遗漏的东西:
- 客户端证书 .cer 不包含私钥!
我做了什么:
我使用以下命令将 .cer 文件转换为 PEM 格式:
openssl x509 -inform der -in ClientCert.cer -out ClientCert.pem
我用我的私钥创建了一个 .pfx 证书:
openssl pkcs12 -export -in ClientCert.pem -inkey mykey.key -out ClientCert.pfx
然后安装 .pfx 证书一切顺利。
我希望有人觉得它有用。
我在使用 Soap Web 服务(w/att.) 和需要客户端证书身份验证(相互?)的 MTOM 时遇到问题。
在写我已经尝试过的内容之前,我会向您展示我为获得客户证书所做的工作:
- 我用
openssl command openssl genrssa -out mykey.key 2048
生成了一个 RSA 密钥
- 我用这个密钥生成了一个 CSR:
openssl req -new -key mykey.key -out mycsr.csr
- 我已将此 CSR 发送给 Web 服务所有者以接收 客户端证书 ,他们给了我一个签名证书:certificate.cer
现在我已经获得了我的客户端证书,我已将它添加到我的证书存储区 Trusted Root Certification Authority.
下现在代码:
首先,我在 Visual Studio 中创建了一个测试项目,并使用服务的 WSDL 添加了一个服务引用。
然后我写了几行代码:
' Setting TLS 1.2 protocol '
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
ServicePointManager.ServerCertificateValidationCallback = Function(sender1, certificate, chain, sslPolicyErrors)
Return True
End Function
'Creating endpoint and binding'
Dim endpoint As EndpointAddress = New EndpointAddress("https://myWebService.it/service-page")
Dim sslBinding As BasicHttpBinding = New BasicHttpBinding(BasicHttpSecurityMode.Transport)
'Setting CredentialType = Certificate'
sslBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate
'Getting the client certificate from the store'
Dim coll = New X509Store(StoreName.My, StoreLocation.CurrentUser)
coll.Open(OpenFlags.ReadOnly)
Dim cert = coll.Certificates.Find(X509FindType.FindByThumbprint, "76DB1454D4B25ACEAF2BAE465C310E3119278792", True)
'Creating the service'
Dim svc As SdITrasmissioneFileClient = New SdITrasmissioneFileClient(sslBinding, endpoint)
'Setting the certificate inside client credentials'
svc.ClientCredentials.ClientCertificate.Certificate = cert(0)
svc.Open()
'Calling the service'
Dim resp As RispostaEsito_Type = svc.Esito(New Esito_Type() With {.IDFile = "4454555"})
svc.Close()
它对我来说看起来很简单,但是当我执行我的代码时,我得到一个
System.ServiceModel.Security.MessageSecurityException: 'The HTTP request was forbidden with client authentication scheme 'Anonymous'.'
Internal Exception: WebException: Remote Server Error: (403) Forbidden
接下来我使用 Fiddler 和 Wireshark 分析了流量,我发现在客户端和服务器之间的 TLS 握手期间,客户端不会将证书发送到服务器。
现在我不明白为什么,即使我将证书添加到客户端凭据,它也不会发送到目的地。
经过大量阅读,我发现了我遗漏的东西:
- 客户端证书 .cer 不包含私钥!
我做了什么:
我使用以下命令将 .cer 文件转换为 PEM 格式:
openssl x509 -inform der -in ClientCert.cer -out ClientCert.pem
我用我的私钥创建了一个 .pfx 证书:
openssl pkcs12 -export -in ClientCert.pem -inkey mykey.key -out ClientCert.pfx
然后安装 .pfx 证书一切顺利。
我希望有人觉得它有用。