it-swarm.com.de

SSL-Client-Zertifikat-Authentifizierung

Ist es möglich, ein Programm zu erstellen, das die Clientzertifikatauthentifizierung nur mit öffentlichem und privatem Schlüssel verwendet (ich habe kein Zertifikat generiert, ich habe nur öffentlichen und privaten Schlüssel).

Ich möchte einfach eine Authentifizierung auf einem Server mit Client-Zertifikat-Authentifizierung durchführen. Es ist jedoch schwierig, ein Client-Zertifikat programmgesteuert zu erstellen.

Ich möchte die Clientzertifikatauthentifizierung nur mit öffentlichem und privatem Schlüssel durchführen (ich habe nur öffentlichen und privaten Schlüssel, kein Zertifikat).

Es ist möglich, einen öffentlichen Serverschlüssel anstelle eines Clientzertifikats für die Clientzertifikatauthentifizierung zu senden?

10
Taleh Ibrahimli

Zertifikate sind nur der öffentliche Schlüssel mit einem zusätzlichen Kontext. Der Name des Schlüssels, Signaturen, Verwendungsrichtlinien usw. SSL/TLS hängt ab von diesem Kontext. Andernfalls weiß der Host, zu dem Sie eine Verbindung herstellen, nicht, ob der Schlüssel wirklich Ihnen gehört oder nicht. Der SSL-Vertrauensmechanismus basiert auf dem Konzept explizit vertrauenswürdiger Zertifikate und der implizit vertrauenswürdigen Zertifikate, die sie signieren.

Wenn Sie jedoch kein SSL oder TLS verwenden, kann die Verschlüsselung auch ohne SSL erfolgen, aber das Vertrauen muss auf eine andere Weise erfolgen. SSH ist ein gutes Beispiel dafür: SSH verwendet weiterhin öffentliche und private Schlüssel. Da es jedoch keine Hierarchie von Signaturen gibt, sind die zusätzlichen Informationen, die Zertifikate bereitstellen, nicht hilfreich, sodass der Schlüssel nackt gesendet wird. Stattdessen fragt der Client Sie, ob Sie dem öffentlichen Schlüssel des Servers beim ersten Herstellen einer Verbindung vertrauen sollen oder nicht, und überprüft danach jedes Mal, ob der öffentliche Schlüssel mit dem übereinstimmt, was er zuletzt gesehen hat. Dies kann passieren, weil SSH kein SSL oder TLS für seine Verschlüsselung verwendet.

Wenn Sie jedoch das SSL-Protokoll verwenden, schreibt das Protokoll vor, dass dem öffentlichen Schlüssel der hinzugefügte Kontext des Zertifikats angezeigt werden muss. Das heißt, das Zertifikat ist der Container, in den der öffentliche Schlüssel gestellt werden muss, damit SSL ihn verwenden kann.

Wenn Sie über den privaten Schlüssel verfügen, ist es trivial, ein selbstsigniertes Zertifikat mit einem Tool wie OpenSSL zu erstellen.

11
tylerl

SSL/TLS unterstützt die Clientauthentifizierung mit einem Zertifikat. Was intern wirklich passiert, ist Folgendes:

  • Der Server fordert ein "Client-Zertifikat" über eine CertificateRequest -Nachricht an.
  • Der Client sendet sein Zertifikat als Certificate -Nachricht und berechnet außerdem eine Signatur (unter Verwendung seines privaten Schlüssels) für alle vorhergehenden Nachrichten im Handshake. Die Signatur wird als CertificateVerify Nachricht gesendet.
  • Der Server erhält irgendwie den öffentlichen Clientschlüssel (normalerweise durch Dekodieren des Clientzertifikats als X.509 Zertifikat und Validieren in auf X.509-Weise und extrahiert dann den öffentlichen Schlüssel daraus) und verwendet ihn, um die Signatur vom Client zu überprüfen.

Im Protokoll selbst werden Zertifikate jedoch als undurchsichtige Byteblöcke ausgetauscht. Jedes "Zertifikat" wird mit einem 3-Byte-Header gesendet, der seine Länge angibt. Wenn Sie also sowohl Server- als auch Client-Code steuern, liegt es ganz bei Ihnen, zu entscheiden, wie diese Byte-Blöcke interpretiert werden sollen. Sie müssen kein X.509-Zertifikat senden. Wenn Sie möchten, können Sie eine leere Nachricht senden.

Die wichtigen Punkte bleiben:

  • Damit die Authentifizierung sinnvoll ist, muss der Server den öffentlichen Schlüssel des Clients mit einer gewissen Garantie kennen. Die Signatur zeigt, dass der Client den privaten Schlüssel steuert. Dies ist jedoch nur dann von Nutzen, wenn der entsprechende öffentliche Schlüssel eindeutig mit einer bekannten Clientidentität verknüpft ist.

  • Das Schlüsselpaar muss von einem für Signaturen geeigneten Typ sein (d. H. RSA oder DSA, nicht Diffie-Hellman).

Bestehende SSL-Implementierungen können darauf bestehen , zumindest das X.509-Format zu respektieren. In diesem Fall müssen Sie Ihren öffentlichen Schlüssel in eine Art selbstsigniertes Format einschließen X.509-Zertifikat, das mit einigen Bibliotheken wie OpenSSL programmgesteuert relativ einfach ist.

Es gibt ein Standard zum Ersetzen von X.509-Zertifikaten in SSL durch öffentliche OpenPGP-Schlüssel, um die Formatagilität zu demonstrieren, die SSL innewohnt.

9
Thomas Pornin

(Dies basiert auf meiner Antwort auf dieselbe Frage zu SO . Es ist oft besser, nur auf einer SE-Site zu fragen.)

Das TLS-Protokoll ermöglicht nur den Austausch von Zertifikaten, keine öffentlichen Rohschlüssel. Sogar "PGP-Schlüssel" (wenn Sie X.509 durch OpenPGP für die Authentifizierung in TLS ersetzen möchten, was viel weniger unterstützt wird) sind tatsächlich Zertifikate (sie sind die signierte Kombination eines öffentlichen Schlüssels und einer Reihe von Bezeichnern und Attributen).

Wie Thomas sagt, könnten Sie möglicherweise Ihren eigenen Zertifikatstyp definieren und ihn zu einem einfachen öffentlichen Schlüssel machen (obwohl ich nicht sicher bin, ob sie technisch noch als "Zertifikate" bezeichnet werden können).

Aus praktischer Sicht sollten Sie in der Lage sein, mit vorhandenen SSL/TLS-Stacks das zu erreichen, was Sie benötigen, und den Umgang mit den X.509-Verifizierungszertifikaten zu optimieren, mit Vorsicht. In der Tat stellen die meisten SSL/TLS-Stapel die Überprüfung von X.509-Zertifikaten über ihre APIs bereit, aber nur wenige lassen andere Arten von Zertifikaten (z. B. OpenPGP) zu oder ermöglichen eine einfache Anpassung des Codes. Die Anpassung für Nicht-X.509-Zertifikate kann sehr schwierig sein, zu zusätzlichen Fehlern führen, wenn Sie mit der SSL/TLS-Implementierung noch nicht vertraut sind, und auch in der Praxis schwierig bereitzustellen sein, da alle potenziellen Clients auch Ihre Anpassungen unterstützen müssten .

Sie können die Clientauthentifizierung mit selbstsignierten Client-X.509-Zertifikaten durchführen und sich auf deren öffentliche Schlüssel () verlassen. Sie müssen diesen öffentlichen Schlüssel jedoch anhand von Informationen überprüfen, die Ihr Server bereits kennt, z. B. eines bekannten Liste ). Sie müssen zuerst die Sicherheitsauswirkungen für die Implementierung verstehen. Dies ist nicht ganz das gleiche Problem wie bei selbstsignierten Serverzertifikaten. (Ich würde vorschlagen, einen traditionelleren Ansatz zur Überprüfung des Serverzertifikats beizubehalten.)

Sie können den Client veranlassen, ein selbstsigniertes Zertifikat zu senden (möglicherweise mit bestimmten Tricks bezüglich der vom Server angekündigten CA-Liste ) und entweder die Überprüfung im TLS-Stack oder später im Anwendung.

Beachten Sie, dass viele Anwendungscontainer (z. B. Tomcat/Jetty in Java) erwarten, dass die SSL/TLS-Schicht das Clientzertifikat überprüft. Wenn Sie dort die Authentifizierung überspringen (und dies später im Container oder als Teil der Anwendung bevorzugen), werden viele Anwendungsframeworks verwirrt. Sie müssen sehr vorsichtig sein, um sicherzustellen, dass die Authentifizierung tatsächlich irgendwo durchgeführt wird, bevor Sie eine Aktion ausführen, die eine Authentifizierung in Ihrer Anwendung erfordert.

Beispielsweise kann es in Ordnung sein, einen Vertrauensmanager zu haben, der jedes Clientzertifikat in Tomcat/Jetty durchlässt, aber Sie können sich nicht darauf verlassen, dass das Anforderungsattribut javax.servlet.request.X509Certificate In irgendeiner Weise überprüft wurde (was die meisten Frameworks tun) würde sonst erwarten). Sie müssten eine Überprüfungslogik in Ihrer Anwendung implementieren: Zum Beispiel einen Filter vor einer authentifizierten Funktion, die den öffentlichen Schlüssel in diesem Clientzertifikat mit Ihrer bekannten Liste öffentlicher Schlüssel vergleicht (oder wie auch immer Sie den öffentlichen Schlüssel abgleichen möchten eine Kennung). Alternativ können Sie diese Überprüfung auch in Ihrem benutzerdefinierten Vertrauensmanager (in Java) durchführen. Dies erfordert weniger Arbeit in den Anwendungen.

Sie könnten etwas Ähnliches in einem Apache Httpd + PHP Setup (zum Beispiel) mit SSLVerifyClient optional_no_ca Ausführen. Auch dies konnte Ihre PHP Anwendung nicht) Verlassen Sie sich darauf, dass das Zertifikat überprüft wurde, sodass Sie diese Überprüfung auch dort durchführen müssen.

Tun Sie dies nur, wenn Sie wissen, zu welchem ​​Zeitpunkt die erhaltenen Zertifikatinformationen überprüft wurden.

2
Bruno

zusätzlich zu unserem lieben freund tylerl

sie sollten über OpenSSL Linux-Befehle Bescheid wissen und über gute Programmierkenntnisse in PHP oder Perl. (speziell PHP) verfügen. Hier finden Sie eine gute Anleitung dazu: 1 - http: // www. php.net/manual/en/book.openssl.php und 2-openssl. org Sie müssen über fundierte Kenntnisse des Befehls openssl und seiner Funktionen verfügen.

am Ende: (Ihre Frage) Ist es möglich, einen öffentlichen Serverschlüssel anstelle eines Clientzertifikats für die Clientzertifikatauthentifizierung zu senden? Nein, weil Sie möglicherweise das TLS-Handshake-Protokoll vergessen haben, das Schritt für Schritt die Authentifizierung und den Schlüsselaustausch zwischen Client und Server anzeigt. http://msdn.Microsoft.com/en-us/library/windows/desktop/aa380513%28v=vs.85%29.aspx

0
Passenger