Wie füge ich SSL ein .net-Anwendung, die httplistener - es wird *nicht* auf dem IIS ausgeführt wird

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

Frage

Jüngste änderungen in bold Ich bin mit dem .net HttpListener Klasse, aber ich bin nicht auf dem IIS ausgeführt wird und bin nicht mit ASP.net.Diese web site beschreibt, was der code tatsächlich in Gebrauch implementieren von SSL mit asp.net und diese Seite beschreibt das einrichten der Zertifikate (obwohl ich nicht sicher bin, ob es funktioniert nur für IIS oder nicht).

Die Klasse Dokumentation beschreibt verschiedene Arten der Authentifizierung (basic, digest, Windows, etc.) --- keiner von Ihnen beziehen sich auf SSL.Es besagt, dass, wenn HTTPS verwendet wird, müssen Sie ein server-Zertifikat.Ist das eine one-line-Eigenschaft die Einstellung und HttpListener Figuren aus den rest der Welt?

Kurz gesagt, ich muss wissen, wie man die Zertifikate und so ändern Sie den code zum implementieren von SSL.

Obwohl er nicht auftreten, wenn ich versuche, auf HTTPS, bemerkte ich einen Fehler in meinem System Event log der Quelle "Schannel" und der Inhalt der Nachricht:

Ein schwerwiegender Fehler ist aufgetreten, wenn Sie versuchen für den Zugriff auf SSL-server Anmeldeinformationen privaten Schlüssel.Der zurückgegebene Fehlercode vom kryptografischen Modul 0 x 80090016.

Edit:
Die bisherigen Schritte

  • Erstellt eine funktionierende HTTPListener in C#, das funktioniert für HTTP-verbindungen (z.B."http://localhost:8089/foldername/"
  • Erstellt ein Zertifikat mit makecert.exe
  • Hinzugefügt die Zertifikat vertraut werden mit certmgr.exe
  • Verwendet Httpcfg.exe hören für SSL-verbindungen auf einem test-port (z.B.8090)
  • Hinzugefügt port 8080 an den HTTPListener über Hörer.Präfixe.Add(https://localhost:8090/foldername/");
  • getestet eine HTTP-client-Verbindung, z.B.(http://localhost:8089/foldername/") in einem browser und Sie erhalten die richtige Rückkehr
  • getestet eine HTTPS-client-Verbindung, z.B.(http://localhost:8090/foldername/") in einem browser und empfangen "Datenübertragung Unterbrochen" (Firefox)
  • debugging in visual studio zeigt, dass die listener-Rückruf erhält, dass die Anfragen, die Sie nie getroffen wird, wenn die HTTPS-Verbindung gestartet wird - ich sehe keine Stelle, könnte ich einen Haltepunkt zu fangen alles andere zuvor.
  • netstat zeigt, dass die listening-ports sind offen für HTTPS und HTTP.der HTTPS-port geht, um TIME_WAIT wenn eine Verbindung versucht wird.
  • Fiddler und HTTPAnalyzer nicht fangen jede der Verkehr, ich denke, es wird nicht weit genug in den Prozess zu zeigen, bis in diese HTTP-Analyse-tools

Fragen

  • Was könnte das problem sein?
  • Ist es ein Stück .Net-code, den ich vermisst werde (was bedeutet, ich habe mehr zu tun C# andere als einfach ein Präfix hinzufügen, um die Zuhörer, die Punkte zu HTTPS, das ist, was ich getan habe)
  • Haben eine verpasst, eine Konfiguration Schritt irgendwo?
  • Was sonst könnte ich tun, um das problem zu analysieren?
  • Wird die Fehlermeldung in das Ereignisprotokoll des Systems ein Zeichen für das problem?Wenn ja, wie würde es behoben werden?

Keine korrekte Lösung

Andere Tipps

Ich habe ein ähnliches problem, und es scheint, dass es könnte ein problem mit dem Zertifikat selbst.

Hier ist der Pfad, der für mich gearbeitet:

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

dann schauen Zertifikat Fingerabdruck,, in die Zwischenablage kopieren und Leerzeichen entfernen.Dies wird ein parameter nach -h in den nächsten Befehl:

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

dann führen Sie einen service-host auf https://localhost:801/ und es funktioniert perfekt.

was kann ich machen das arbeiten ist für https laufen auf selbst generierte Zertifikat.Hier ist der code, den ich ausführen zu generieren (Fehlerbehandlung für Klarheit):

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

Zertifikat-shows in Ordnung und es hat eine funktionierende private Schlüssel, aber https-timeout als ob Fingerabdruck wurde nie registriert.Wenn jemand weiß, warum - plz Kommentar

EDIT1:Nach einigem Herumspielen fand ich die Initialisierung für CertCreateSelfSignCertificate generiert entsprechende Zertifikat:

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;

Sie müssen nur um ein Zertifikat zu binden, um eine ip:port und öffnen Sie den listener mit https:// Präfix.0.0.0.0 gilt für alle ip ist.appid ist eine zufällige GUID, und certhash ist der hash des Zertifikats (manchmal genannt ein thumprint).

Führen Sie die folgenden mit cmd.exe mit Administratorrechten an.

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

Wenn Sie möchten, erstellen Sie ein selbstsigniertes Zertifikat,um dies zu testen

  1. Öffnen Sie den IIS -
  2. Klicken Sie auf Ihrem computer name
  3. Klicken Sie auf Server-Zertifikate Symbol
  4. Klicken Sie auf " generate Self-Signed Zertifikat
  5. Doppel-klicken Sie auf und gehen auf die details
  6. Sehen Sie den Fingerabdruck gibt, so entfernen Sie die Leerzeichen.

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

Nach dem ausführen dieses Programm, das ich gerade navigiert wird https://localhost:1234 zu sehen, dass der text gedruckt.Da das Zertifikat CN entspricht nicht der url und es ist nicht in das Trusted Shop Zertifikat erhalten Sie eine zertifikatswarnung.Der text ist verschlüsselt, jedoch, wie Sie überprüfen können, mit einem tool wie Draht Hai.

Wenn Sie genauer Steuern möchten, erstellen Sie ein selbstsigniertes X. 509-Zertifikat openssl ist ein großartiges Werkzeug, und es ist eine Portierung für windows.Ich hatte viel mehr Erfolg mit sich als das tool makecert.


Es ist auch sehr wichtig, dass, wenn Sie die Kommunikation mit dem https-Dienst, der code hat eine ssl-Warnung, Sie müssen die setup-Zertifikat validator auf dem service-point-manager zu umgehen, ist es für Testzwecke.

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

Ich habe es nicht vollständig implementiert, aber diese web-site zu geben scheint, eine gute Exemplarische Vorgehensweise für die Einrichtung der Zertifikate und der code.

Hier ist eine alternative Möglichkeit zum binden der SSL-certifiate, um die IP - /PORT-Kombination, ohne Verwendung von httpcfg.exe (Windows XP) oder netsh.exe (Vista+).

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

Das wesentliche ist, dass Sie verwenden können, ein C++ HttpSetServiceConfiguration API-in-built-in windows zu tun, es programmgesteuert und nicht über die Befehlszeile, daher entfernen die Abhängigkeit auf das OS und httpcfg installiert.

Die Klasse Dokumentation

hat dieser Hinweis:

Wenn Sie ein HttpListener mit https ist, müssen Sie einen Server auswählen, Zertifikat für die Zuhörer.Ansonsten ein HttpWebRequest-Abfrage diese HttpListener schlägt fehl mit unerwartete schließen der Verbindung.

und dieses:

Sie können konfigurieren Sie Server-Zertifikate und andere listener-Optionen mit HttpCfg.exe.Finden http://msdn.microsoft.com/library/default.asp?url=/library/en-us/http/http/httpcfg_exe.asp für mehr details.Die ausführbare Datei ist im Lieferumfang von Windows Server 2003 oder gebaut werden kann, aus dem source-code im Plattform-SDK verfügbar.

Ist der erste Hinweis, erklärt sich durch die zweite?Wie in der Frage verwendet habe ich httpcfg.exe binden Sie das Zertifikat an einem bestimmten port.Wenn Sie wollen etwas anderes als dies, der Hinweis ist mehrdeutig.

Ich angetroffen habe das gleiche Problem wie Sie.Glücklicherweise nach googeln harte Schritte auf diese Seite SSL arbeitet mit meinem HttpListener.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top