close
Kaspersky Endpoint Security

Welcome to

Kaspersky Endpoint Security


By Kaspersky Endpoint Security


Meine Projekte



15, Dezember 2015
Ich beschloss, einen Prototyp für eine zu tun, so dass ich untersucht, wie TLS-Client-Authentifizierung mit einem Java / Frühjahr Server-Seite zu tun (lesen Sie auf, auch wenn Sie kein Java-Entwickler sind - die meisten von der Post ist java-Agnostiker) . Warum TLS-Client-Authentifizierung? Denn das ist die Standardmethode zur Authentifizierung eines Benutzers, der ein Zertifikat (auf einer Smartcard, zum Beispiel) besitzt. Natürlich sind Smartcard-Zertifikate nicht die einzige Anwendung - Organisationen interne Zertifikate an Benutzer erteilen kann, dass sie auf ihren Rechnern speichern. Der Punkt ist, einen Authentifizierungsmechanismus zu haben, das sicherer ist als ein einfacher Benutzername / Passwort-Paar ist. Es ist ein Usability-Problem, vor allem bei Smart Cards, aber das ist über den Rahmen dieses Beitrags. Also, mit TLS ClientAuth, zusätzlich zu der Serveridentität durch den Client (über den Server-Zertifikat) überprüft wird, wird die Client-Identität auch durch den Server überprüft. Dies bedeutet, dass der Kunde ein Zertifikat, das von einer Behörde ausgestellt wird, die der Server explizit vertraut.Grob gesagt, hat der Kunde auf digital eine Herausforderung, um unterschreiben zu beweisen, dass es den privaten Schlüssel besitzt, die mit dem Zertifikat entspricht es präsentiert. (Dieser Vorgang kann auch unter gefunden werden) Es gibt zwei Möglichkeiten, das zu nähern. Die erste und die meisten intuitiv, ist zu prüfen, wie Tomcat zu konfigurieren (oder Ihr Servlet-Container). Das gibt die Tomcat-Konfiguration an der Unterseite. Die "Schlüsselspeicher" ist der Speicher, in dem das Server-Zertifikat (+ privater Schlüssel) gespeichert ist, und "trusts" ist der Laden, die das Root-Zertifikat der Behörde hält, die die Client-Zertifikate zu unterzeichnen verwendet wird. Allerdings ist diese Konfiguration nur anwendbar, wenn Sie ein einzelnes Servlet-Container-Instanz an die Benutzer ausgesetzt haben. Wahrscheinlich in der Produktion, aber finden Sie eine Reihe von Instanzen / Knoten haben Ihre Anwendung ausgeführt wird, hinter einem Load-Balancer, und an der Lastenausgleich, die dann die entschlüsselten Anfragen an den Servlet-Container über einen einfachen HTTP-Verbindung weiterleitet. In diesem Fall sind Ihre Möglichkeiten, entweder nicht zubeenden TLS an der Lastenausgleich, das ist keine gute Idee, höchstwahrscheinlich ist, oder Sie haben irgendwie von Ihrem Lastenausgleich zu Ihrem Knoten das Client-Zertifikat zu übermitteln. Ich werde nginx als Beispiel verwenden. Generieren der Schlüsselpaare, Zertifikate, Zertifikatsanforderungen, signierte Zertifikate und Schlüsselspeicher ist ein separater Post wert. . Sie müssen OpenSSL und keytool / und eine Reihe von Befehlen. Für die Produktion, natürlich ist es noch komplizierter, weil für das Serverzertifikat eine CSR an eine Zertifizierungsstelle benötigen würde zu schicken das getan, in Ihrer nginx Konfiguration, sollten Sie so etwas wie haben: Server {    hören 443 ssl;    server_name yourdomain.com;    ssl_certificate server.cer;    # Das ist der private Schlüssel    ssl_certificate_key server.key;    #, Die das Zertifikat der CA hält, die die Client-Zertifikate unterzeichnet, denen Sie vertrauen. = Trusts in tomcat    ssl_client_certificate ca.pem;    # Dies zeigt an, ob die Client-Authentifizierung erforderlich ist, oder optional (ClientAuth = "true" vs"Wollen" in tomcat)    ssl_verify_client auf;    Lage / {       # Proxy_pass Konfiguration hier, inclding X-Forwarded-For-Header. Hinweis: seien Sie besonders vorsichtig für nicht X-client-Zertifikat Weiterleitung gefälschter Kopf       proxy_set_header X-client-Zertifikat $ SSL_CLIENT_CERT;    } }  So kann der Client-Zertifikat als Header weitergeleitet wird (). Das sieht aus wie ein Hack, und es ist wahrscheinlich, weil das Client-Zertifikat nicht gerade eine kleine Zeichenfolge ist. Aber das ist der einzige Weg, ich denken kann. . Es gibt ein kleines Problem damit, aber (und es ist das gleiche für die Tomcat-Lösung als auch) - wenn Sie die Client-Authentifizierung für die gesamte Domain aktivieren, können Sie nicht völlig ungeschützt Seiten haben. Auch wenn die Authentifizierung optional ( "wollen") ist, der Browser-Dialog (aus dem der Benutzer wählt ein Zertifikat) würde immer noch egal ausgelöst werden, welche Seiten der Benutzer zuerst öffnet. Die gute Sache ist, dass ein Benutzer ohne Zertifikat noch in der Lage sein würde, Seiten zu durchsuchen, die nicht explizit geschütztmit Code. Aber für eine Person, die ein Zertifikat hat, die Homepage öffnen würde den Dialog zu öffnen, auch wenn er vielleicht nicht wollen, zu authentifizieren. Es ist etwas, das getan werden kann, um es zu verarbeiten. Ich habe es eigentlich mit Perl "pro Seite" getan gesehen, aber ich bin nicht sicher, kann dies mit einem Java-Setup durchgeführt werden. Nun, es kann, wenn Sie nicht mit einem Servlet-Container, sondern behandeln Ihre TLS-Handshakes selbst. Aber das ist nicht wünschenswert. Normalerweise würden Sie den Browser-Authentifizierung nur für einen einzigen URL-Dialog benötigen. "/ Login", oder, wie in meinem Fall mit der "/ authentifizieren" Endpunkt (der Benutzer der Identity Provider weitergeleitet wird / authentifizieren URL, wo normalerweise würde er Benutzername / Passwort einzugeben, aber in diesem Fall würde er nur das richtige Zertifikat auswählen). Was getan werden kann, ist, dass bestimmte Endpunkt von einer Sub-Domain zuzugreifen. Das wäre ein weiteres "Server" in der nginx Konfiguration mit dem subodmain und der ssl_verify_client bedeuten, die auf, während die reguläre Domain ohne Client bleibtZertifikatsüberprüfung. Auf diese Weise werden nur Anfragen an die Sub-Domain authentifiziert werden. Nun, wie die eigentliche Authentifizierung zu tun. Die OpenID Connect Implementierung oben erwähnt verwendet Feder Sicherheit, aber es kann alles sein. unterstützt beide Fälle oben (tomcat und nginx tomcat) erwähnt. Das macht die Anwendung Lastenausgleich-aware, aber Sie können sicher die eine oder andere Ansatz wählen und die andere Hälfte aus dem Code loszuwerden. Für die einzelnen tomcat Ansatz wird die X509Certificate einfach durch diese Linien erhalten:     X509Certificate Zert [] = (X509Certificate []) Anfrage        .getAttribute ( "javax.servlet.request.X509Certificate");     // Überprüfen, ob nicht leer und bekommen das erste  Für die nginx-in-Front-Ansatz, ist es ein bisschen komplizierter. Wir müssen den Header erhalten, verwandeln es zu einem ordnungsgemäßen Zustand und dann analysieren. (Beachten Sie, dass ich die Feder-Sicherheit X509-Filter nicht verwendet, da es nur die Single-Katers Ansatz unterstützt.) String certificateHeader =request.getHeader ( "X-client-Zertifikat"); if (certificateHeader == null) {     response.sendError (HttpServletResponse.SC_UNAUTHORIZED);     Rückkehr; } // Der Load Balancer (zum Beispiel nginx) leitet das Zertifikat // In einen Kopf durch neue Zeilen mit Leerzeichen ersetzt // (2 oder mehr). Auch Tabs ersetzen, die manchmal nginx // Anstelle von Leerzeichen senden String certificate = certificateHeader      .ReplaceAll ( "\\ s {2,}", System.lineSeparator ())      .ReplaceAll ( "\\ t ", System.lineSeparator ()); usercertificate = (X509Certificate) certificateFactory     .generateCertificate (neu ByteArrayInputStream (         certificateContent.getBytes ( "ISO-8859-11")));  Die "hackiness" ist jetzt offensichtlich, weil die Art und Weise nginx die certiciate sendet PEM-kodierte, aber auf einer Linie. Glücklicherweise sind die Linien, die durch irgendeine Art von Leerzeichen getrennt (einmal war es Räume, ein anderes Mal ist es Registerkarten war (auf einem Windows-Rechner)), so können wir sie in ihre ursprüngliche PEM-Format zurückkehren (auch ohnenotwendigerweise zu wissen, dass eine PEM-Linie 64 Zeichen ist). Es kann sein, dass andere Versionen von nginx oder andere Server keine Leerzeichen gesetzt, so dass die Aufspaltung in 64-Zeichenzeilen aufweisen erfolgen. Dann haben wir ein X.509-Zertifikat Fabrik verwenden, um ein Zertifikat-Objekt erstellen. Das ist im Grunde es. Dann können wir verwenden, um die CN (Common Name), oder jede andere eindeutig identifizierende Feld zu extrahieren, aus dem Zertifikat, und verwenden Sie den entsprechenden Benutzerdatensatz aus der Datenbank zu laden. Das ist es, oder zumindest das, was ich von meinem Proof-of-concept bekam. Es ist eine Nische Use-Case, und, aber für nationale sichere E-ID Systeme, für E-Banking und für interne Anwendungen ist es wahrscheinlich keine schlechte Idee. Filed under: von Bozho
Hinterlasse eine Antwort

Endpoint-Security 2012     Endpoint-Security-10

Categories and tags