2012-03-23 89 views
2

我正在構建一個使用vb.net的web服務客戶端。 Web服務使用ssl,基本身份驗證進行安全保護,並且還需要客戶端證書。因此,我創建在Visual Studio的Web引用和提供的憑據:如何使用客戶端證書/相互認證來調用Web服務?

Dim cred As New System.Net.NetworkCredential("usr", "passwd") 
Dim proxy As New SimpleFromLocal.simple 
proxy.Credentials = cred 

Console.WriteLine(proxy.helloWorld()) 

可正常工作,只要我關掉相互認證在服務器端。 我說像這樣的客戶端證書:

Dim cert As X509Certificate = X509Certificate.CreateFromCertFile(certFile) 
proxy.ClientCertificates.Add(cert) 

證書加載,但Web服務調用失敗。我可以發佈例外情況,但它是用德語發佈的,這本身就是一個問題。它基本上說:驗證失敗,因爲遠程站點關閉了連接。 我試着調試服務器端的ssl握手,看起來客戶端證書沒有被傳輸。

那麼我在這裏錯過了什麼?是否需要在本地機器上安裝客戶端證書?

編輯:引發的錯誤:

System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> 
System.IO.IOException: Authentication failed because the remote party has closed the transport stream. 
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) 
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) 
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) 
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) 
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) 
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) 
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) 
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) 
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) 
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) 
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) 
at System.Net.TlsStream.CallProcessAuthentication(Object state) 
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result) 
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size) 
at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size) 
at System.Net.ConnectStream.WriteHeaders(Boolean async) 
--- End of inner exception stack trace --- 
at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request) 
at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request) 
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) 
at CCClient.SimpleFromLocal.simple.helloWorld() in C:\TP\CCClient\CCClient\Web References\SimpleFromLocal\Reference.vb:Zeile 90. 
at CCClient.Module1.clientWithProxy(NetworkCredential cred, String certFile) 
in C:\TP\CCClient\CCClient\Module1.vb:Zeile 53. 

回答

3

終於來了!

This question讓我嘗試使用X509Certificate2(注意類名中的)。我將它與僅包含單個證書的PKCS#12密鑰庫一起使用。因此,這裏是我做過什麼:

創建密鑰庫文件

我用Java的keytool這一點。創建一個自簽名證書後,需要導出到所需的格式:

keytool -importkeystore -srckeystore keystore.jks \ 
     -srcstoretype JKS \ 
     -destkeystore keystore.pfx \ 
     -deststoretype PKCS12 

注:導出證書到一個文件,並使用它直接不起作用。

添加客戶端證書代理

Dim proxy As New SimpleFromLocal.simple 
Dim cred As New NetworkCredential("usr", "passwd") 
Dim cert As New X509Certificate2(certFile, "passwd") 
proxy.Credentials = cred 
proxy.ClientCertificates.Add(cert) 

Console.WriteLine(proxy.helloWorld()) 

就是這樣。無論出於何種原因,使用X509Certificate都會導致相同的設置失敗。

+0

在.NET中,有時需要指定握手 System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3; //使用SSL3避免握手問題 – 2016-09-26 01:45:16

相關問題