Cum adaug SSL într-o aplicație .net care folosește httplistener - nu va fi * executată pe IIS

Most recent edits in bold I am using the .net HttpListener class, but I'm won't be running on IIS and am not using ASP.net. This web site describes what code to actual use to implement SSL with asp.net and this site describes how to set up the certificates (although I'm not sure if it works only for IIS or not).

Documentația de clasă descrie diferite tipuri de autentificare (de bază, digest, Windows etc.) --- nici unul nu se referă la SSL. Se spune că dacă se utilizează HTTPS, va trebui să setați o server . Este vorba de o setare de proprietate într-o singură linie și HttpListener compară restul?

Pe scurt, trebuie să știu cum să configurez certificatele și cum să modific codul pentru a implementa SSL.

Deși nu se întâmplă când încerc să accesez HTTPS, am observat o eroare în jurnalul de evenimente al sistemului - sursa este "Schannel", iar conținutul mesajului este:

A apărut o eroare fatală la încercare   pentru a accesa acreditările serverului SSL   cheia privată. Codul de eroare a revenit   din modulul criptografic este   0x80090016.

Edit:
Steps taken so far

Întrebări

  • Care ar putea fi problema?
  • Există o bucată de cod Net. Îmi lipsește (ceea ce înseamnă că trebuie să fac mai mult în C# altfel decât să adaug un prefix ascultătorului care indică HTTPS, ceea ce am făcut)
  • Aveți un pas de configurare dorit undeva?
  • Ce altceva ar trebui să fac pentru a analiza problema?
  • Este mesajul de eroare din jurnalul de evenimente al sistemului un semn al problemei? Dacă da, cum ar fi stabilit?
0
fr hi bn

5 răspunsuri

Încă nu am implementat-o ​​în întregime, dar acest site pare să ofere un bună introducere a setării certificatelor și a codului.

0
adăugat

The class documentation

are această notă:

Dacă creați un HttpListener utilizând   https, trebuie să selectați un server   Certificat pentru acel ascultător.   În caz contrar, o interogare HttpWebRequest de   acest HttpListener va eșua cu un   închiderea neașteptată a conexiunii.

și asta:

Aveți posibilitatea să configurați Certificate Server   și alte opțiuni de ascultător prin utilizarea   Httpcfg.exe. Vedea    http: // msdn .microsoft.com / biblioteca / default.asp? url = / biblioteca / en-ne / http / http / httpcfg_exe.asp   pentru mai multe detalii. Executivul este   livrat împreună cu Windows Server 2003, sau   poate fi construit din codul sursă   disponibile în platforma SDK.

Este prima notă explicată de al doilea? Așa cum am subliniat în întrebare, am folosit httpcfg.exe pentru a lega certificatul la un anumit port. Dacă intenționează altceva decât acest lucru, nota este ambiguă.

0
adăugat

Trebuie să legați un certificat de un port ip: și apoi să-l deschideți pe ascultător cu un prefix https: //. 0.0.0.0 se aplică tuturor ip-urilor. este orice GUID aleatoriu și certhash este hash-ul certificatului (uneori numit thumprint).

Rulați următoarele cu cmd.exe utilizând privilegiile de administrator.

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

Dacă doriți să creați un certificat auto-semnat pentru a testa acest lucru,

  1. Open IIS
  2. Click on your computer name
  3. Click Server Certificates icon
  4. Click generate Self-Signed certificate
  5. Double click and go to details
  6. You will see the thumbprint there, just remove the spaces.

    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();
    

După rularea acestui program am navigat la https: // localhost: 1234 pentru a vedea textul imprimat. Deoarece certificatul CN nu se potrivește cu adresa URL și nu se află în magazinul Certificat de încredere, veți primi un avertisment privind certificatul. Textul este criptat, totuși, așa cum puteți verifica cu un instrument cum ar fi Wire Shark.

Dacă doriți mai mult control asupra creării unui certificat x509 auto-semnat, openssl este o unealtă excelentă și există un port pentru ferestre. Am avut mult mai multe succese decât instrumentul makecert.


De asemenea, este foarte important ca, dacă comunicați cu un serviciu https de la un cod care are un avertisment SSL, trebuie să configurați validatorul de certificat în managerul de puncte de service pentru al ocoli în scopuri de testare.

ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, errors) => true;
0
adăugat

Am o problemă similară și se pare că ar putea exista o problemă cu certificatul în sine.

Iată calea care mi-a ajutat:

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

apoi căutați certificatul amprente , copiați-l în clipboard și eliminați spațiile. Acesta va fi un parametru după -h în următoarea comandă:

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

apoi rulați o gazdă de servicii pe https: // localhost: 801 / și funcționează perfect.

ceea ce nu pot face munca este ca https să ruleze pe certificatul auto-generat. Iată codul pe care l-am executat pentru a genera unul (tratarea erorilor luată pentru claritate):

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);

Certificatul se dovedește bine și are o cheie privată de lucru, dar https va expira ca și cum amprenta nu a fost înregistrată niciodată. Dacă cineva știe de ce - plz comentariu

EDIT1: After some playing around, I have found the initialization for CertCreateSelfSignCertificate which generates proper certificate:

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;
0
adăugat

Iată o modalitate alternativă de a lega certificatul SSL la combinația IP / PORT fără a utiliza httpcfg.exe (XP) sau netsh.exe (Vista +).

http://dotnetcodebox.blogspot.com .au / 2012/01 / cum-la-munca-cu-ssl-certificate.html

Esența este că puteți utiliza un C ++ HttpSetServiceConfiguration API încorporat în Windows pentru a face acest lucru, mai degrabă decât prin intermediul programatic linia de comandă, prin urmare, eliminând dependența de sistemul de operare și având httpcfg instalat.

0
adăugat
Am publicat acest cod ca un pachet Nuget . Simțiți-vă libertatea să o utilizați.
adăugat autor Serghei Gorodetki, sursa