我試圖通過他們的WSDL創建與Web服務的連接。我被告知服務的身份驗證通過交換證書來描述爲帶有身份驗證的TLS。我通過visual studio中的「添加服務引用」生成客戶端。當我發送命令時,我希望看到線鯊中的「握手」,但我甚至沒有看到發送「客戶端Hello」的啓動。具有相互身份驗證的服務客戶端(雙向客戶端證書身份驗證)
服務的認證說明如下: http://en.wikipedia.org/wiki/Transport_Layer_Security#Description
我的客戶是在C#writen
這裏是我運行測試連接完整的程序(它開始運行()):
public class ClientExample
{
private const string Url =
"https://xxxxxxxxx";
public static void Run()
{
ServicePointManager.ServerCertificateValidationCallback += ValidateCertificate;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
PerformTest("Clear Cache", GetBinding());
}
private static Binding GetBinding()
{
var bec = new BindingElementCollection
{
new TextMessageEncodingBindingElement(MessageVersion.Soap12, Encoding.UTF8),
new HttpsTransportBindingElement{ RequireClientCertificate = true }
};
return new CustomBinding(bec);
}
private static void PerformTest(string test, Binding binding)
{
try
{
Console.ResetColor();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(test);
Console.ResetColor();
var client = GetClient(binding);
SendMessage(client);
}
catch (Exception e)
{
DisplayError(e);
}
}
private static MyClient GetClient(Binding binding)
{
var endpointAddress = new EndpointAddress(Url);
var client = new MyClient(binding, endpointAddress);
if (client.ClientCredentials != null)
{
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My,
X509FindType.FindBySubjectName,
"xxxxxxxxxxxxx");
}
return client;
}
private static void SendMessage(ChargePointServiceClient client)
{
var response = client.clearCache("xxxxxxxxxxxxx", new ClearCacheRequest());
Console.WriteLine(ClearCacheDescription(response));
}
private static string ClearCacheDescription(ClearCacheStatus response)
{
switch (response)
{
case ClearCacheStatus.Accepted:
return "Accepted";
case ClearCacheStatus.Rejected:
return "Rejected";
}
return "Unkown";
}
private static bool ValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors)
{
switch (sslpolicyerrors)
{
case SslPolicyErrors.None:
return true;
case SslPolicyErrors.RemoteCertificateChainErrors:
DisplayWarningMessage("RemoteCertificateChainErrors");
return false;
case SslPolicyErrors.RemoteCertificateNameMismatch:
DisplayWarningMessage("RemoteCertificateNameMismatch");
return false;
case SslPolicyErrors.RemoteCertificateNotAvailable:
DisplayWarningMessage("RemoteCertificateNotAvailable");
return false;
default:
DisplayWarningMessage("Unkown Certificate Validation Error");
return false;
}
}
private static void DisplayError(Exception exception)
{
if (exception == null)
return;
Console.BackgroundColor = ConsoleColor.DarkRed;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(@"Exception");
Console.ResetColor();
Console.WriteLine(exception.Message);
if (exception.InnerException != null)
Console.WriteLine();
DisplayError(exception.InnerException);
}
private static void DisplayWarningMessage(string message)
{
Console.BackgroundColor = ConsoleColor.DarkYellow;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(message);
Console.ResetColor();
}
}
我登錄通過system.diagnostic所有網絡流量在我的app.config:
<system.diagnostics>
<sources>
<source name="System.Net">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Sockets">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Cache">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
</sources>
<switches>
<add name="System.Net" value="Verbose"/>
<add name="System.Net.Sockets" value="Verbose"/>
<add name="System.Net.Cache" value="Verbose"/>
</switches>
<sharedListeners>
<add name="System.Net"
type="System.Diagnostics.TextWriterTraceListener"
traceOutputOptions="None"
initializeData="network.log"
/>
</sharedListeners>
<trace autoflush="true"/>
</system.diagnostics>
這裏有一些感興趣的日誌行:
這證實了一個TLS流創建:創建
System.Net Information: 0 : [9040] TlsStream#50727427::.ctor(host=xxxxx, #certs=1)
安全通道:
System.Net Information: 0 : [9040] SecureChannel#11159819::.ctor(hostname=xxxxxxx, #clientCertificates=1, encryptionPolicy=RequireEncryption)
System.Net Information: 0 : [9040] Enumerating security packages:
System.Net Information: 0 : [9040] Negotiate
System.Net Information: 0 : [9040] NegoExtender
System.Net Information: 0 : [9040] Kerberos
System.Net Information: 0 : [9040] NTLM
System.Net Information: 0 : [9040] TSSSP
System.Net Information: 0 : [9040] pku2u
System.Net Information: 0 : [9040] Schannel
System.Net Information: 0 : [9040] Microsoft Unified Security Protocol Provider
System.Net Information: 0 : [9040] LiveSSP
System.Net Information: 0 : [9040] WDigest
System.Net Information: 0 : [9040] CREDSSP
System.Net Information: 0 : [9040] SecureChannel#11159819 - Attempting to restart the session using the user-provided certificate: [Version]
不知道爲什麼要查找私鑰:
System.Net Information: 0 : [9040] SecureChannel#11159819 - Left with 1 client certificates to choose from.
System.Net Information: 0 : [9040] SecureChannel#11159819 - Trying to find a matching certificate in the certificate store.
System.Net Information: 0 : [9040] SecureChannel#11159819 - Locating the private key for the certificate: [Version]
在此日誌中,我看到證書已交換。不幸的是絲鯊並不確認這個...
現在我的程序驗證的服務證書,並開始處理
System.Net Information: 0 : [9040] SecureChannel#11159819 - Remote certificate was verified as valid by the user.
System.Net Information: 0 : [9040] ProcessAuthentication(Protocol=Ssl3, Cipher=Rc4 128 bit strength, Hash=Sha1 160 bit strength, Key Exchange=RsaKeyX 2048 bit strength).
然後我看到了一些加密的數據交換和我清除緩存命令發送
我收到來自服務的加密響應,但消息指示出現故障。我想這是因爲身份驗證不是由服務
System.Net Error: 0 : [9040] Exception in HttpWebRequest#46890055::GetResponse - The remote server returned an error: (500) Internal Server Error..
這裏接受的(包括IP地址是服務不是我)
(ip.src == xxx.xxx.xxx.xx or ip.dst == xxx.xxx.xxx.xx) and ssl.handshake
而且,證書我使用Wireshark的中過濾器我正在使用沒有私鑰。我認爲我不應該需要TLS文檔中的一個。
所以我的問題是爲什麼我在運行程序時在wireshark中看不到Client Hello/Server Hello,或者應該如何配置客戶端綁定以啓動客戶端hello?
(我標記WCF,因爲我認爲WCF的專業人士可能知道答案,我的問題。我的解決方案將是獨立的WCF的,因爲我沒有服務綁定的控件)
這是我不清楚的部分。我被告知通過瀏覽器下載證書,我下載的證書沒有私鑰。當我打開證書時,它會顯示「此證書用於以下目的:*承認遠程計算機的身份*將您的身份證明給遠程計算機。」對我而言,我似乎只是向服務提供證書以證明身份,然後通過我提供的維基鏈接中描述的步驟4進行加密。 – aelstonjones
我假設瀏覽器在訪問https站點時會有相同的機制。瀏覽器不會擁有私鑰,但通信最終會被加密。 – aelstonjones
你從哪裏下載證書?這是來自證書頒發機構嗎?通常情況下,如果您使用證書頒發機構生成新證書,則CA不會獲取或生成私鑰,該私鑰只在發出請求的計算機上生成,然後在您身份時將密鑰與證書進行匹配將它下載回同一臺機器。 – tomasr