Используя C #, я могу установить соединение SSL с помощью индикации имени сервера (SNI)? - PullRequest
11 голосов
/ 30 марта 2012

В настоящее время у меня есть этот код, который устанавливает 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 возвращается неправильный сертификат.Есть ли способ установить SSL-соединение с использованием SNI?

Я использую .NET 2 (при необходимости готов к обновлению).Я использую Windows 7, но хотел бы, чтобы программное обеспечение работало на других платформах, таких как Windows 2008, если это возможно.

Ответы [ 4 ]

2 голосов
/ 20 апреля 2013

Таким образом, в заключение кажется, что ответ таков: нет, вы не можете заставить соединение TLS использовать SNI: - (

Я не смог найти пример кода C #, устанавливающий соединение TLS с SNI. Теоретически, однако, должно быть возможно создать это вручную, то есть согласно Как реализовать индикацию имени сервера (SNI)

однако, попытка здесь потерпела неудачу: TLS SNI с C #

0 голосов
/ 21 марта 2015

Я знаю, что это старый пост, но недавно мне понадобилось то же самое.У меня есть приложение на C #, которое я использовал для динамического создания сайтов на C #.При создании привязок сайта мне потребовалось установить флаг «указание имени сервера», поскольку мы пытаемся использовать несколько сайтов SSL на одном IP-адресе.

Как оказалось, теперь вы МОЖЕТЕ сделать это в 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 голосов
/ 03 июля 2014

Мы столкнулись с подобной проблемой при попытке подключиться к бизнес-API с использованием взаимного SSL. Стандартные библиотеки .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, прокси-серверы, куки-файлы, аутентификацию пользователя + пароль (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;
}
0 голосов
/ 18 мая 2013

Ответ, кажется, "да", так как есть реализация C #, которая поддерживает SNI. В этом отчете об ошибке упоминается версия mono, поддерживающая HTTPS-запросы с SNI.

...