Последние правки выделены жирным шрифтом.
Я использую класс .net HttpListener
, но я не буду запускать это приложение на IIS и не использую ASP.net. Этот веб-сайт описывает, какой код нужно использовать для реализации SSL в asp.net, а этот сайт описывает, как установить сертификаты (хотя я не уверен, что это работает только для IIS или нет).
В документации класса описаны различные типы аутентификации (basic, digest, Windows и т.д.) - ни один из них не относится к SSL. Там говорится, что если используется HTTPS, вам нужно будет установить сертификат сервера. Будет ли это установка свойства в одну строку, а HttpListener
сам разберется с остальным?
Короче говоря, мне нужно знать, как установить сертификаты и как изменить код для реализации SSL.
Хотя это не происходит, когда я пытаюсь получить доступ к HTTPS, я заметил ошибку в журнале системных событий - источником является "Schannel", а содержание сообщения следующее:
Произошла фатальная ошибка при попытке получить доступ к учетным данным сервера SSL. закрытый ключ. Код ошибки, возвращенный от криптографического модуля. 0x80090016.
Редактировать: Шаги, предпринятые на данный момент
Вопросы
У меня есть подобная проблема, и кажется, что могла быть проблема с самим свидетельством.
Here' s путь, который работал на меня:
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://localhost:801/, и он работает отлично.
то, что я не могу сделать работой, для https, чтобы работать на самопроизведенном свидетельстве. Here' s кодекс я бегу, чтобы произвести один (обработка ошибок, вынутая для ясности):
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;
Вы просто должны связать свидетельство ip:port и затем открыть Вашего слушателя с https://префикс. 0.0.0.0 относится ко всему ip' s. appid является любым случайным GUID, и certhash - мешанина свидетельства (иногда названный thumprint).
Управляйте следующим с cmd.exe использование привилегий администратора.
netsh http add sslcert ipport=0.0.0.0:1234 certhash=613bb67c4acaab06def391680505bae2ced4053b appid={86476d42-f4f3-48f5-9367-ff60f2ed2cdc}
Если Вы хотите создать самоподписанное свидетельство, чтобы проверить это,
Открытый IIS
Нажмите на свое имя компьютера
Нажмите символ Server Certificates
Щелчок производит Самоподписанное свидетельство
Дважды щелкните и пойдите в детали
Вы будете видеть след большого пальца там, просто удалять места.
Слушатель HttpListener = новый HttpListener ();
слушатель. Префиксы. Добавьте (" https://+:1234/");
слушатель. Начните ();
Пульт. WriteLine (" Слушание...");
Контекст HttpListenerContext = слушатель. GetContext ();
использование (Поток потока = контекст. Ответ. OutputStream)
использование (автор StreamWriter = новый StreamWriter (поток))
писатель. Напишите (" привет, https world");
Пульт. ReadLine ();
После управления этой программой я просто провел к 'https://localhost:1234', чтобы видеть напечатанный текст. Начиная со свидетельства CN не соответствует URL, и это не находится в Хранилище сертификатов, которому Доверяют, Вы получите Предупреждение Свидетельства. Текст зашифрован однако, поскольку Вы можете проверить с инструментом как Жесткошерстная Акула.
Если Вы хотите больше контроля над созданием самоподписанного x509 свидетельства openssl, большой инструмент и есть порт для окон. I' ve имел намного больше успеха с ним, чем makecert инструмент.
It' s также очень важный, что к тому, если Вы общаетесь с https обслуживанием из кодекса, у которого есть предупреждение ssl, Вы должны установка контрольное устройство свидетельства на менеджере сервисного центра, чтобы обойти его для тестирования целей.
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, errors) => true;
У меня еще не все реализовано, но на этом сайте есть хорошее руководство по настройке сертификатов и кода.
Вот альтернативный способ связать 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][2] API, встроенный в окна, чтобы сделать это программно, а не через командную строку, следовательно удаляя зависимость от OS и имея httpcfg установленный.
[2]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364503 (v=vs.85) .aspx
содержит следующее примечание:
Если вы создаете HttpListener, используя https, вы должны выбрать серверный Сертификат для этого слушателя. В противном случае, запрос HttpWebRequest к > этому HttpListener'у. этого HttpListener потерпит неудачу с > неожиданным закрытием. неожиданным закрытием соединения.
и это:
Вы можете настроить сертификаты сервера (Server Certificates) и другие параметры слушателя, используя 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 для привязки сертификата к определенному порту. Если они имеют в виду что-то другое, то примечание двусмысленно.
Я'столкнулся с той же проблемой, что и вы. К счастью, после гугления трудные шаги на этой странице заставили SSL работать с моим HttpListener.