2012-03-30 26 views
11

Actualmente tengo el código que hace una conexión SSL con el servidor:Usando C# ¿puedo hacer una conexión SSL usando la Indicación del nombre del servidor (SNI)?

using (client = new TcpClient()) 
{ 

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


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

Sin embargo, no creo que soporta SNI porque el certificado incorrecto se devuelve desde el servidor configurado SNI. ¿Hay alguna forma de hacer la conexión SSL usando SNI?

Estoy usando .NET 2 (dispuesto a actualizar si es necesario). Estoy usando Windows 7, pero me gustaría que el software funcione en otras plataformas, como Windows 2008 si es posible.

+0

Sería de gran ayuda para conocer en detalles que las versiones de Windows .Net y que está utilizando, ya que el apoyo SNI dependerá de ellos. – Bruno

+0

@Bruno Buen punto: he actualizado la pregunta. – TonyM

+2

Parece que es posible que necesite una biblioteca externa en lugar de 'SslStream': http://connect.microsoft.com/VisualStudio/feedback/details/729925/net-4-4-5-sslstream-no-supports-the-tls-server-name-indication-sni – Bruno

Respuesta

2

Para concluir, parece como si la respuesta es: No, no hay manera de que se puede realizar la conexión TLS utilizar :-(SNI

no pude encontrar ningún ejemplo de código C# hacer una conexión TLS . con SNI en teoría, sin embargo, debería ser posible crear manualmente, es decir, según How to implement Server Name Indication (SNI)

embargo

, un intento por aquí no: TLS SNI with C#

0

La respuesta parece ser "sí", ya que hay un C# implementación que admite SNI. This bug report menciona la versión de mono que admite HTT Solicitudes de PS con SNI.

0

Nos enfrentamos a un problema similar al tratar de conectarnos a la API de negocios mediante SSL mutuo. Las bibliotecas .NET estándar no funcionan. Puede usar la biblioteca de terceros http://curl.haxx.se/libcurl/ como una de las posibles soluciones.

libcurl es una biblioteca libre y fácil de usar de transferencia de URL del lado del cliente, apoyando DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP , RTSP, SCP, SFTP, SMTP, SMTPS, Telnet y TFTP. libcurl admite certificados SSL, HTTP POST, HTTP PUT, carga de FTP, carga basada en formularios HTTP, proxies, cookies, autenticación de usuario + contraseña (Básico, Resumen, NTLM, Negociar, Kerberos), reanudación de transferencia de archivos, túnel proxy http y más.

biblioteca .NET se puede cargar desde http://sourceforge.net/projects/libcurl-net/

Al cargar cambia libcurl.dll a la última versión se puede encontrar (debe ser 7.18.1 o posterior). En el paquete libcurl-nel actual, es anterior a lo necesario.

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

Sé que esta es una publicación anterior, pero recientemente necesitaba lo mismo. Tengo una aplicación en C# que utilicé para crear sitios web dinámicamente en C#. Necesitaba los enlaces del sitio para establecer el indicador de "indicación del nombre del servidor" cuando se creó, porque estamos tratando de usar varios sitios SSL en la misma dirección IP.

Como resultado, ahora PUEDE hacerlo en C#. Hay una opción de indicador que puede aprobar que activará la opción SNI. Espero que esto ayude a cualquiera que tenga este problema. Aquí está un ejemplo:

// 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 pidió una solución de cliente, no del lado del servidor. –

Cuestiones relacionadas