本文介绍了使用 TLS 1.2 和 WCF 客户端证书身份验证使用第三方 Soap web 服务时出现 503 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用需要客户端证书身份验证(相互?)的 Soap Web 服务(带附件)和 MTOM 时遇到问题.

I've got a problem consuming a Soap Web Service(w/att.) and MTOM that requires client certificate authentication (mutual?).

在编写我已经尝试过的内容之前,我向您展示了我为获得客户端证书所做的工作:

Before writing what i've already tried i show you what i did in order to receive a client certificate:

  1. 我已经使用 openssl 命令 openssl genrssa -out mykey.key 2048
  2. 生成了一个 RSA 密钥
  3. 使用这个密钥,我生成了一个 CSR:openssl req -new -key mykey.key -out mycsr.csr
  4. 我已将此 CSR 发送给网络服务所有者以接收客户端证书,他们给了我一个签名证书:certificate.cer
  1. I've generated a RSA key with openssl command openssl genrssa -out mykey.key 2048
  2. With this key i've generated a CSR: openssl req -new -key mykey.key -out mycsr.csr
  3. I've sent this CSR to the web service owner in order to receive a client certificate, and they gave me a signed certificate: certificate.cer

现在我已经获得了我的客户端证书,我已经将它添加到了受信任的根证书颁发机构下的证书存储中.

Now that i've got my client certificate i've added it in my certificate store under Trusted Root Certification Authority.

现在代码:

首先,我在 Visual Studio 中创建了一个测试项目,并使用服务的 WSDL 添加了一个服务引用.

First of all i created a Test Project in Visual Studio and i added a Service Reference using the WSDL of the service.

然后我写了几行代码:

' 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()

对我来说看起来很简单,但是当我执行我的代码时,我得到一个

It looks very simple to me, but when i execute my code i get a

System.ServiceModel.Security.MessageSecurityException:'HTTP请求被客户端身份验证方案匿名"禁止.

内部异常:WebException:远程服务器错误:(403) 禁止

Internal Exception: WebException: Remote Server Error: (403) Forbidden

接下来我使用 Fiddler 和 Wireshark 分析了流量,我发现在客户端和服务器之间的 TLS 握手期间,客户端不会将证书发送到服务器.

Next i analyzed traffic using Fiddler and Wireshark and i discovered that, during TLS handshake between client and server, the client doesn't send the certificate to the server.

现在我不明白为什么,即使我将证书添加到客户端凭据中,它也不会发送到目的地.

推荐答案

经过大量阅读,我发现了我所缺少的:

After a lot of readings, i discovered what i was missing:

  • 客户端证书 .cer 不包含私钥!

我做了什么:

  1. 我使用以下命令将 .cer 文件转换为 PEM 格式:

  1. I converted .cer file in PEM format with the following command:

openssl x509 -inform der -in ClientCert.cer -out ClientCert.pem

openssl x509 -inform der -in ClientCert.cer -out ClientCert.pem

我用我的私钥创建了一个 .pfx 证书:

I created a .pfx certificate with my private key:

openssl pkcs12 -export -in ClientCert.pem -inkey mykey.key -out ClientCert.pfx

openssl pkcs12 -export -in ClientCert.pem -inkey mykey.key -out ClientCert.pfx

然后安装 .pfx 证书一切正常.

Then installing .pfx certificate everything works like a charm.

我希望有人觉得它有用.

I hope somebody find it usefull.

这篇关于使用 TLS 1.2 和 WCF 客户端证书身份验证使用第三方 Soap web 服务时出现 503 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-29 11:43
查看更多