Come faccio ad aggiungere SSL per un .net applicazione che utilizza la classe httplistener - *non* essere in esecuzione in IIS

StackOverflow https://stackoverflow.com/questions/4004

Domanda

I più recenti modifiche in grassetto Io sto usando la .net HttpListener di classe, ma io non sia in esecuzione in IIS e non sto usando ASP.net.Questo sito web descrive il tipo di codice che uso effettivo implementazione di SSL con asp.net e questo sito viene descritto come impostare i certificati (anche se non so se funziona solo per IIS o non).

La documentazione descrive vari tipi di autenticazione (di base, digest, Windows, etc.) --- nessuno di loro si fa riferimento a SSL.Dire che se HTTPS viene utilizzato, è necessario impostare un server certificato.Ci sarà una linea di impostazione della proprietà e HttpListener figure il resto?

In breve, ho bisogno di sapere come impostare i certificati e come modificare il codice per implementare il protocollo SSL.

Anche se non si verificano quando sto cercando di accesso HTTPS, ho fatto notare un errore nel mio registro Eventi di Sistema - la sorgente "Schannel" e il contenuto del messaggio è il seguente:

Un fatale errore durante il tentativo per accedere al server SSL credenziali chiave privata.Il codice di errore restituito il modulo di crittografia è 0x80090016.

Edit:
Le misure finora adottate

  • Creati un lavoro la classe httplistener in C# che funziona per le connessioni HTTP (ad es."http://localhost:8089/foldername/"
  • Creato un certificato utilizzando makecert.exe
  • Aggiunto il certificato attendibile utilizzando certmgr.exe
  • Usato Httpcfg.exe ascoltare per le connessioni SSL su un test della porta (es.8090)
  • Aggiunto porta 8080 per la classe httplistener via ascoltatore.Prefissi.Add(https://localhost:8090/foldername/");
  • testato un client HTTP collegamento, ad es.(http://localhost:8089/foldername/") in un browser e ricevere di ritorno corretto
  • testato un client HTTPS connessione, ad esempio(http://localhost:8090/foldername/") in un browser e ricevere "Trasferimento Dati Interrotto" (in Firefox)
  • debug in visual studio mostra che l'ascoltatore di callback che riceve le richieste non viene mai colpito quando la connessione HTTPS inizia - non vedo nessun luogo che ho potuto impostare un punto di interruzione per la cattura di qualsiasi altra cosa in precedenza.
  • netstat mostra che l'ascolto porte sono aperte sia per HTTPS e HTTP.la porta HTTPS non andare TIME_WAIT dopo un tentativo di connessione.
  • Fiddler e HTTPAnalyzer non prendere qualsiasi del traffico, credo che non ottenere abbastanza lontano nel processo di presentarsi in quei HTTP strumenti di analisi

Domande

  • Quale può essere il problema?
  • C'è un pezzo di .Net codice mi manca (nel senso che devo fare di più in C# altri semplicemente di aggiungere un prefisso per l'ascoltatore che punti a HTTPS, che è quello che ho fatto)
  • Hanno perso un passaggio di configurazione da qualche parte?
  • Cos'altro potrei fare per analizzare il problema?
  • È il messaggio di errore nel registro Eventi di Sistema un segno del problema?Se è così come sarebbe risolto?

Nessuna soluzione corretta

Altri suggerimenti

Ho un problema simile, e sembra che ci potrebbe essere un problema con il certificato stesso.

Ecco il percorso che ha funzionato per me:

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

quindi cercare certificato identificazione personale, copiare il contenuto negli appunti e rimuovere gli spazi.Questo sarà un parametro-h nel comando successivo:

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

quindi l'esecuzione di un servizio host https://localhost:801/ e funziona perfettamente.

quello che non riesco a fare il lavoro è per l'https per eseguire sul certificato autofirmato.Ecco il codice che ho eseguito per generare uno (gestione degli errori per chiarezza):

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

Certificato dimostra bene e si ha una chiave privata, ma https timeout come se l'identificazione non è mai stato registrato.Se qualcuno sa perché - cap commento

EDIT1:Dopo qualche partita in giro, ho trovato l'inizializzazione per CertCreateSelfSignCertificate che genera certificato:

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;

Devi solo associare un certificato ip:porta e quindi aprire il tuo ascoltatore con un prefisso https://.0.0.0.0 si applica a tutti gli ip.appid è qualsiasi GUID casuale, e certhash è l'hash del certificato (a volte chiamato un thumprint).

Eseguire le operazioni seguenti cmd.exe utilizzando i privilegi di amministratore.

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

Se si desidera creare un certificato autofirmato per eseguire questo test,

  1. Open IIS
  2. Fare clic sul nome del computer
  3. Fare clic su Server Certificati icona
  4. Fare clic su genera certificato Auto-Firmato
  5. Fare doppio clic e vai al dettaglio
  6. Vedrete l'identificazione personale c'è, basta rimuovere gli spazi.

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

Dopo l'esecuzione di questo programma ho appena navigato https://localhost:1234 per vedere il testo stampato.Dato che il certificato CN non corrisponde l'url e non è il Certificato Attendibile store si otterrà un Avviso di Certificato.Il testo è crittografato tuttavia, come si può verificare con uno strumento come il Filo di Squalo.

Se si desidera maggiore controllo sulla creazione di un auto-firmato il certificato x509 openssl è un grande strumento e c'è una porta per windows.Ho avuto molto più successo con il makecert strumento.


E ' anche molto importante che se si sta comunicando con un servizio https, dal codice che ha un avviso ssl, è necessario configurare il certificato di convalida sui service manager del punto di bypass per scopi di test.

ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, errors) => true;

Io non sono del tutto ancora implementato, ma questo sito sembra dare un buona progressione l'impostazione di certificati e il codice.

Ecco un modo alternativo per associare il SSL certifiate per la combinazione IP/PORTA senza l'utilizzo di httpcfg.exe (XP) o netsh.exe (Vista+).

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

L'essenza di esso è che si può utilizzare un C++ HttpSetServiceConfiguration API integrato in windows per farlo a livello di programmazione, piuttosto che tramite la riga di comando, quindi rimuovere la dipendenza del sistema operativo e avere httpcfg installato.

Il documentazione di classe

è questa nota:

Se si crea un'utilizzando la classe httplistener https, è necessario selezionare un Server Certificato per la ascoltatore.In caso contrario, un HttpWebRequest query di questa la classe httplistener verrà effettuata con un inaspettata chiusura della connessione.

e questo:

È possibile configurare il Server di Certificati e ascoltatore opzioni utilizzando HttpCfg.exe.Vedere http://msdn.microsoft.com/library/default.asp?url=/library/en-us/http/http/httpcfg_exe.asp per ulteriori dettagli.Il file eseguibile è fornito con Windows Server 2003 o può essere costruito a partire dal codice sorgente disponibile in Platform SDK.

È la prima nota spiegato dal secondo?Come indicato nella domanda, ho usato httpcfg.exe per associare il certificato di una porta specifica.Se si intende qualcosa di diverso da questo, la nota è ambiguo.

Ho riscontrato lo stesso problema come voi.Fortunatamente dopo googling hard passaggi su questa pagina fare SSL a lavorare con la mia la classe httplistener.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top