2012-03-30 57 views
11

目前,我有這個代碼,使SSL連接到服務器:使用C#可以使用服務器名稱指示(SNI)進行SSL連接嗎?

using (client = new TcpClient()) 
{ 

    client.Connect(Hostname, Port); 
    var callback = new RemoteCertificateValidationCallback(ValidateServerCertificate); 


    using (stream = new SslStream(client.GetStream(), false, callback)) 
    { 
     stream.AuthenticateAsClient(Hostname); 
    } 
} 

不過,我不認爲它支持SNI,因爲錯誤的證書正在從SNI配置的服務器返回。無論如何要使用SNI進行SSL連接?

我正在使用.NET 2(如果需要,願意升級)。我正在使用Windows 7,但希望軟件可以在其他平臺(如Windows 2008)上運行。

+0

這將有助於在.Net和Windows版本您正在使用的,因爲SNI支持將取決於這些細節就知道了。 – Bruno 2012-03-30 16:24:21

+0

@布魯諾好點 - 我已經更新了這個問題。 – TonyM 2012-03-30 16:32:22

+2

看起來你可能需要一個外部庫而不是'SslStream':http://connect.microsoft。com/VisualStudio/feedback/details/729925/net-4-4-5-sslstream-no-supports-the-tls-server-name-indication-sni – Bruno 2012-03-30 17:48:08

回答

2

因此斷定它好像答案是:不,有沒有辦法,可以使TLS連接使用SNI :-(

我找不到任何C#示例代碼進行TLS連接。符合SNI從理論上講,雖然,它應該可以手動創建,按照How to implement Server Name Indication (SNI)

然而即試圖在這裏失敗:TLS SNI with C#

0

答案似乎是「是」,因爲有一個C#實現支持SNI This bug report提到支持HTT的單聲道版本PS與SNI的請求。

0

我們遇到了類似的問題,試圖使用相互SSL連接到業務API。標準.NET庫不起作用。您可以使用第三方庫http://curl.haxx.se/libcurl/作爲可能的解決方案之一。

libcurl是一款免費且易於使用的客戶端URL傳輸庫,支持DICT,FILE,FTP,FTPS,Gopher,HTTP,HTTPS,IMAP,IMAPS,LDAP,LDAPS,POP3,POP3S,RTMP ,RTSP,SCP,SFTP,SMTP,SMTPS,Telnet和TFTP。 libcurl支持SSL證書,HTTP POST,HTTP PUT,FTP上傳,基於HTTP表單的上傳,代理,cookies,用戶名密碼認證(Basic,Digest,NTLM,Negotiate,Kerberos),文件傳輸恢復,http代理隧道等。

.NET庫可以從http://sourceforge.net/projects/libcurl-net/

當你上傳libcurl.dll改變到最新版本,你可以找到(它應該是7.18.1或更新版本)上傳。在當前的libcurl-nel包中,它比需要的要舊。

public string HTTPGet(string URL, string Proxy, string certName = null, string certPassword = null) 
{ 
    Easy easy = new Easy(); 
    SockBuff = ""; 
    try 
    { 
     Easy.WriteFunction wf = new Easy.WriteFunction(OnWriteData); 
     easy.SetOpt(CURLoption.CURLOPT_URL, URL); 
     easy.SetOpt(CURLoption.CURLOPT_TIMEOUT, "60"); 
     easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf); 
     easy.SetOpt(CURLoption.CURLOPT_USERAGENT, UserAgent); 
     easy.SetOpt(CURLoption.CURLOPT_COOKIEFILE, CookieFile); 
     easy.SetOpt(CURLoption.CURLOPT_COOKIEJAR, CookieFile); 
     easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, true); 

     if (!string.IsNullOrEmpty(certName)) 
     { 
      easy.SetOpt(CURLoption.CURLOPT_SSLCERT, certName); 
      if (!string.IsNullOrEmpty(certPassword)) 
      { 
       easy.SetOpt(CURLoption.CURLOPT_SSLCERTPASSWD, certPassword); 
      } 
     } 

     if (URL.Contains("https")) 
     { 
      easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYHOST, 1); 
      easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER, 0); 
     } 

     if (!string.IsNullOrEmpty(Proxy)) 
     { 
      easy.SetOpt(CURLoption.CURLOPT_PROXY, Proxy); 
      easy.SetOpt(CURLoption.CURLOPT_PROXYTYPE, CURLproxyType.CURLPROXY_HTTP); 
     } 

     var code = easy.Perform(); 
     easy.Cleanup(); 
     Console.WriteLine(code); 
    } 
    catch 
    { 
     Console.WriteLine("Get Request Error"); 
    } 

    return SockBuff; 
} 

public static Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb, Object extraData) 
{ 
    // Console.Write(System.Text.Encoding.UTF8.GetString(buf)); 
    SockBuff = SockBuff + System.Text.Encoding.UTF8.GetString(buf); 

    return size * nmemb; 
} 
-2

我知道這是一個較舊的帖子,但我最近需要同樣的東西。我在C#中有一個應用程序,用於在C#中動態創建網站。我需要該站點的綁定來創建「服務器名稱指示」標誌,因爲我們試圖在同一個IP地址上使用多個SSL站點。

事實證明,你現在可以在C#中做到這一點。你可以通過一個標誌選項打開SNI選項。我希望這有助於任何有此問題的人。這裏有一個例子:

// Create site using server manager 
 
ServerManager sm = new ServerManager(); 
 
Site mySite = sm.Sites.Add("example.com", "C:\Test Website\", 443); 
 

 
// Creating binding object to store SSL cert 
 
var ibind = mySite.Bindings.CreateElement(); 
 
ibind.Protocol = "https"; 
 
ibind.BindingInformation = "*:443:" + domain; 
 
ibind.CertificateHash = certificate.GetCertHash(); 
 

 
// This option will turn on SNI (server name indication) 
 
ibind.SetAttributeValue("sslFlags", 1); 
 

 
// Add the binding to the site 
 
mySite.Bindings.Add(ibind);

+0

OP詢問客戶端解決方案,而不是服務器端。 – 2015-10-05 22:00:55

相關問題