Как добавить SSL в .NET приложение, которое использует HttpListener - это * не * быть запущена на IIS

голоса
37

Самые последние правки в смелом Я использую .net HttpListenerкласс, но я не буду работать на IIS и я не использую ASP.net. Этот веб - сайт описывает , какой код фактического использования для осуществления SSL с asp.net и этот сайт описывает , как установить сертификаты (хотя я не уверен, что это работает только для IIS или нет).

Документация класса описывает различные типы аутентификации (базовая, дайджест, Windows и т.д.) --- ни один из них не относятся к SSL. Он сказал , что если используется HTTPS, вам нужно будет установить сертификат сервера . Будет ли это быть значение свойства одной строки и HttpListenerцифры из остальные?

Короче говоря, мне нужно знать, как настроить сертификаты и как изменить код для реализации SSL.

Хотя это не происходит, когда я пытаюсь получить доступ к HTTPS, я заметил ошибку в моем журнале системных событий - источник «Schannel» и содержание сообщения является:

при попытке получить доступ к серверу SSL удостоверения закрытого ключа произошла неисправимая ошибка. Код ошибки, возвращаемый из криптографического модуля 0x80090016.

Edit:
Шаги , предпринятые до сих пор

  • Создан рабочий HttpListener в C # , который работает на HTTP - соединений (например , HTTP: // локальный: 8089 / имя_папки /
  • Создано с помощью сертификата Makecert.exe
  • Добавлен сертификат для доверенного использования certmgr.exe
  • Используется Httpcfg.exe для прослушивания SSL соединения на тестовый порт (например, 8090)
  • Добавлен порт 8080 к HttpListener через listener.Prefixes.Add ( https: // локальный: 8090 / имя_папки / «);
  • тестирование соединения HTTP клиента, например ( HTTP: // локальный: 8089 / FOLDERNAME / «) в браузере и получить правильный возврат
  • тестирование соединения HTTPS клиента, например ( HTTP: // локальный: 8090 / FOLDERNAME / «) в браузере и получить„Передача данных Прерванный“(в Firefox)
  • отладка в визуальном студии показывает, что слушатель обратного вызова, который не получает запросы никогда не получает удар, когда начинается подключение HTTPS - я не вижу места, что я мог бы установить контрольную точку, чтобы поймать что-нибудь еще раньше.
  • NetStat показывает, что слушающие порты открыты как для HTTPS и HTTP. порт HTTPS действительно идет к TIME_WAIT после подключения.
  • Скрипач и HTTPAnalyzer не поймать любой трафик, я предполагаю , что он не получает достаточно далека в процессе , чтобы показать в этих инструментах анализа HTTP

Вопросов

  • Что эта проблема может быть?
  • Есть кусок кода .NET мне не хватает (это означает, что я должен сделать больше в C #, кроме просто добавить префикс к слушателю, который указывает на HTTPS, которая является то, что я сделал)
  • Были ли пропущенный шаг конфигурации где-нибудь?
  • Что еще я могу сделать, чтобы проанализировать эту проблему?
  • Является ли сообщение об ошибке в системном журнале событий признаком проблемы? Если это так, как бы это исправить?
Задан 06/08/2008 в 22:18
источник пользователем
На других языках...                            


6 ответов

голоса
9

У меня аналогичная проблема, и кажется, что там может быть проблема с самим сертификатом.

Вот путь, который работал для меня:

makecert.exe -r -a sha1 -n CN=localhost -sky exchange -pe -b 01/01/2000 -e 01/01/2050 -ss my -sr localmachine

затем посмотреть сертификат отпечаток , скопировать его в буфер обмена и удалить пробелы. Это будет параметр после -h в следующей команде:

HttpCfg.exe set ssl -i 0.0.0.0:801 -h 35c65fd4853f49552471d2226e03dd10b7a11755

затем запустить множество услуг на https: // локальный: 801 / и он прекрасно работает.

что я не могу сделать работу для протокола HTTPS для работы на самообразующемся сертификате. Вот код, я бегу, чтобы сгенерировать (обработка ошибок вывезены для ясности):

LPCTSTR pszX500 = subject;
DWORD cbEncoded = 0;
CertStrToName(X509_ASN_ENCODING, pszX500, CERT_X500_NAME_STR, NULL, pbEncoded, &cbEncoded, NULL);
pbEncoded = (BYTE *)malloc(cbEncoded);
CertStrToName(X509_ASN_ENCODING, pszX500, CERT_X500_NAME_STR, NULL, pbEncoded, &cbEncoded, NULL);

// Prepare certificate Subject for self-signed certificate
CERT_NAME_BLOB SubjectIssuerBlob;
memset(&SubjectIssuerBlob, 0, sizeof(SubjectIssuerBlob));
SubjectIssuerBlob.cbData = cbEncoded;
SubjectIssuerBlob.pbData = pbEncoded;

// Prepare key provider structure for self-signed certificate
CRYPT_KEY_PROV_INFO KeyProvInfo;
memset(&KeyProvInfo, 0, sizeof(KeyProvInfo));
KeyProvInfo.pwszContainerName = _T("my-container");
KeyProvInfo.pwszProvName = NULL;
KeyProvInfo.dwProvType = PROV_RSA_FULL;
KeyProvInfo.dwFlags = CRYPT_MACHINE_KEYSET;
KeyProvInfo.cProvParam = 0;
KeyProvInfo.rgProvParam = NULL;
KeyProvInfo.dwKeySpec = AT_SIGNATURE;

// Prepare algorithm structure for self-signed certificate
CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
memset(&SignatureAlgorithm, 0, sizeof(SignatureAlgorithm));
SignatureAlgorithm.pszObjId = szOID_RSA_SHA1RSA;

// Prepare Expiration date for self-signed certificate
SYSTEMTIME EndTime;
GetSystemTime(&EndTime);
EndTime.wYear += 5;

// Create self-signed certificate
pCertContext = CertCreateSelfSignCertificate(NULL, &SubjectIssuerBlob, 0, &KeyProvInfo, &SignatureAlgorithm, 0, &EndTime, 0);
hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"MY");
CertAddCertificateContextToStore(hStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, 0);

Сертификат показывает хорошо, и она имеет рабочий закрытый ключ, но HTTPS будет таймаут, как если бы Отпечаток не был зарегистрирован. Если кто-нибудь знает, почему - плз комментарий

EDIT1 : После того, как некоторые игры вокруг, я нашел инициализацию для CertCreateSelfSignCertificate , который генерирует соответствующий сертификат:

CRYPT_KEY_PROV_INFO KeyProvInfo;
memset(&KeyProvInfo, 0, sizeof(KeyProvInfo));
KeyProvInfo.pwszContainerName = _T("my-container");
KeyProvInfo.pwszProvName = _T("Microsoft RSA SChannel Cryptographic Provider");
KeyProvInfo.dwProvType = PROV_RSA_SCHANNEL;
KeyProvInfo.dwFlags = CRYPT_MACHINE_KEYSET;
KeyProvInfo.cProvParam = 0;
KeyProvInfo.rgProvParam = NULL;
KeyProvInfo.dwKeySpec = AT_KEYEXCHANGE;
Ответил 07/04/2009 d 22:15
источник пользователем

голоса
7

Вы просто должны связать сертификат с IP: порт, а затем открыть слушателю с https: // префикс. 0.0.0.0 применяется ко всем IP. AppID является любой случайный идентификатор GUID и certhash является хэш сертификата (иногда называемый thumprint).

Выполните следующие действия с cmd.exe с использованием прав администратора.

netsh http add sslcert ipport=0.0.0.0:1234 certhash=613bb67c4acaab06def391680505bae2ced4053b  appid={86476d42-f4f3-48f5-9367-ff60f2ed2cdc}

Если вы хотите создать самостоятельно подписанный сертификат, чтобы проверить это,

  1. Открыть IIS
  2. Нажмите на имя компьютера
  3. Нажмите значок сервера сертификатов
  4. Нажмите генерировать сертификат Самозаверяющего
  5. Двойной щелчок и перейти к деталям
  6. Вы увидите отпечаток там, просто удалить пробела.

    HttpListener listener = new HttpListener();
    listener.Prefixes.Add("https://+:1234/");
    listener.Start();
    Console.WriteLine("Listening...");
    HttpListenerContext context = listener.GetContext();
    
    using (Stream stream = context.Response.OutputStream)
    using (StreamWriter writer = new StreamWriter(stream))
        writer.Write("hello, https world");
    
    Console.ReadLine();
    

После запуска этой программы я просто переходите к , https://localhost:1234чтобы увидеть текст напечатанного. Так как сертификат CN не соответствует URL , и это не в хранилище доверенных сертификатов вы получите предупреждение о сертификате. Текст шифруется , однако , как вы можете проверить с помощью инструмента , как Wire Shark.

Если вы хотите получить больше контроля над созданием самоподписанного сертификата x509 OpenSSL является отличным инструментом и есть порт для окон. У меня было гораздо больше успеха с ним, чем инструмент MakeCert.


Кроме того, очень важно, что если вы общаетесь с сервисом по протоколу HTTPS с кодом, который имеет предупреждение SSL, необходимо настроить сертификат проверки подлинности на менеджере точек обслуживания, чтобы обойти его для целей тестирования.

ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, errors) => true;
Ответил 29/09/2012 d 04:55
источник пользователем

голоса
6

У меня нет это еще не полностью реализован, но это веб - сайт , кажется, дают хорошее пошаговое руководство по настройке сертификатов и код.

Ответил 06/08/2008 d 23:29
источник пользователем

голоса
4

Вот альтернативный способ привязать SSL certifiate к комбинации IP / порт без использования httpcfg.exe(XP) или netsh.exe(Vista +).

http://dotnetcodebox.blogspot.com.au/2012/01/how-to-work-with-ssl-certificate.html

Суть ее в том , что вы можете использовать C ++ HttpSetServiceConfiguration API встроенная в окно , чтобы сделать это программно , а не с помощью командной строки, следовательно , удаления зависимости от операционной системы и с httpcfg установлены.

Ответил 02/03/2015 d 05:14
источник пользователем

голоса
3

Документация класса

имеет это к сведению:

При создании HttpListener с использованием протокола HTTPS, необходимо выбрать сертификат сервера для этого слушателя. В противном случае HttpWebRequest запрос этого HttpListener потерпит неудачу с неожиданным закрытием соединения.

и это:

Вы можете настроить сертификаты сервера и другие параметры слушателя с помощью Httpcfg.exe. См http://msdn.microsoft.com/library/default.asp?url=/library/en-us/http/http/httpcfg_exe.asp для более подробной информации. Исполняемый поставляется с Windows Server 2003, или могут быть построены из исходного кода , доступного в Platform SDK.

Объясняется первая записка второй? Как указано в вопросе, я использовал Httpcfg.exe, чтобы связать сертификат к определенному порту. Если они намерены что-то другое, чем это, нота неоднозначна.

Ответил 08/08/2008 d 17:37
источник пользователем

голоса
2

Я столкнулся с такой же вопрос , как вы. К счастью , после того, как прибегая к помощи жестких шагов на этой странице сделать SSL работает с моим HttpListener.

Ответил 28/01/2009 d 11:22
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more