SSH Handshake in einfachen Worten.

Secure Shell (SSH) ist ein weit verbreitetes Transportschichtprotokoll zum Sichern von Verbindungen zwischen Clients und Servern. Dies ist das Grundprotokoll in unserem Teleport- Programm für den sicheren Zugriff auf die Infrastruktur. Nachstehend finden Sie eine relativ kurze Beschreibung des Handshakes, der vor dem Herstellen eines sicheren Kanals zwischen Client und Server und vor dem Starten der vollständigen Verschlüsselung des Datenverkehrs erfolgt.

Versionsfreigabe


Der Handshake beginnt damit, dass sich beide Seiten gegenseitig einen String mit der Versionsnummer senden. In diesem Teil des Handshakes passiert nichts sehr Aufregendes, aber es sollte beachtet werden, dass die meisten relativ modernen Clients und Server aufgrund von Designfehlern in Version 1.0 nur SSH 2.0 unterstützen.

Schlüsselaustausch


Während des Schlüsselaustauschprozesses (manchmal auch als KEX bezeichnet) tauschen die Parteien öffentlich verfügbare Informationen aus und leiten ein Geheimnis ab, das von Client und Server geteilt wird. Dieses Geheimnis kann nicht aus öffentlich zugänglichen Informationen entdeckt oder gewonnen werden.

Schlüsselaustauschinitialisierung


Der Austausch von Schlüsseln beginnt damit, dass beide Seiten sich gegenseitig eine Nachricht SSH_MSG_KEX_INIT mit einer Liste der unterstützten kryptografischen SSH_MSG_KEX_INIT und ihrer bevorzugten Reihenfolge senden.

Kryptografische Grundelemente müssen die Bausteine ​​festlegen, die für den Schlüsselaustausch und anschließend für die vollständige Datenverschlüsselung verwendet werden. In der folgenden Tabelle sind die von Teleport unterstützten kryptografischen Grundelemente aufgeführt.

Schlüsselaustausch (KEX)Symmetrische ChiffreNachrichtenauthentifizierungscode (MAC)Server Host Key Algorithmus
kurve25519-sha256@libssh.orgchacha20-poly1305@openssh.comhmac-sha2-256-etm@openssh.comssh-rsa-cert-v01@openssh.com
ecdh-sha2-nistp256aes128-gcm@openssh.comhmac-sha2-256ssh-rsa
ecdh-sha2-nistp384aes256-ctr
ecdh-sha2-nistp521aes192-ctr
aes128-ctr
Standardkryptografische Grundelemente teleportieren

Initialisierung des Diffie-Hellman-Protokolls auf elliptischen Kurven


Da beide Seiten denselben Algorithmus verwenden, um kryptografische Grundelemente aus der Liste der unterstützten auszuwählen, können Sie nach der Initialisierung sofort mit dem Austausch von Schlüsseln beginnen. Teleport unterstützt nur das ECDH-Protokoll (Elliptic Curve Diffie-Hellman). Der Schlüsselaustausch beginnt also damit, dass der Client ein kurzlebiges Schlüsselpaar (privater und zugehöriger öffentlicher Schlüssel) generiert und dem Server seinen öffentlichen Schlüssel in der Nachricht sendet SSH_MSG_KEX_ECDH_INIT .

Hervorzuheben ist, dass dieses Schlüsselpaar kurzlebig ist: Es wird nur für den Schlüsselaustausch verwendet und dann gelöscht. Dies macht es extrem schwierig, eine Klasse von Angriffen durchzuführen, bei denen ein Angreifer passiv verschlüsselten Verkehr aufzeichnet, in der Hoffnung, den privaten Schlüssel irgendwann in der Zukunft zu stehlen (wie das Gesetz von Yarovaya vorsieht - ca. Trans.). Es ist sehr schwierig, etwas zu stehlen, das nicht mehr existiert. Diese Eigenschaft wird als Vorwärtsgeheimnis bezeichnet.

Abb. 1. Generieren einer Schlüsselaustausch-Initialisierungsnachricht

Diffie-Hellman-Reaktion auf elliptischen Kurven


Der Server wartet auf die SSH_MSG_KEX_ECDH_INIT Nachricht und generiert beim Empfang ein eigenes kurzlebiges Schlüsselpaar. Mit dem öffentlichen Schlüssel des Clients und seinem eigenen Schlüsselpaar kann der Server ein gemeinsames Geheimnis K generieren.

Dann generiert der Server einen sogenannten Exchange-Hash H und signiert ihn, wobei ein signierter HS-Hash generiert wird (mehr in Abb. 3). Der Exchange-Hash und seine Signatur dienen mehreren Zwecken:

  • Da der Austausch-Hash ein gemeinsames Geheimnis enthält, beweist dies, dass die andere Partei ein gemeinsames Geheimnis erstellen konnte.
  • Der Hash- / Überprüfungszyklus der Hash- und Exchange-Signatur ermöglicht es dem Client, zu überprüfen, ob der Server den privaten Schlüssel des Hosts besitzt, und daher ist der Client mit dem richtigen Server verbunden (wenn der Client dem entsprechenden öffentlichen Schlüssel vertrauen kann, dazu später mehr).
  • Durch das Signieren des Hashs anstelle des Signierens der Eingabedaten wird die Größe der zu signierenden Daten erheblich reduziert und führt zu einem schnelleren Handshake.

Der Austausch-Hash wird generiert, indem der Hash (SHA256, SHA384 oder SHA512, abhängig vom Schlüsselaustauschalgorithmus) der folgenden Felder verwendet wird:

  • Magic M Client-Version, Server-Version, Client-Nachricht SSH_MSG_KEXINIT , Server-Nachricht SSH_MSG_KEXINIT .
  • Der öffentliche Schlüssel (oder das Zertifikat) des HPub Serverhosts. Dieser Wert (und der zugehörige private HPriv-Schlüssel) wird normalerweise während der Initialisierung des Prozesses und nicht für jeden Handshake generiert.
  • Öffentlicher Client-Schlüssel
  • Öffentlicher Serverschlüssel B
  • Geteiltes Geheimnis K

Mit diesen Informationen kann der Server die SSH_MSG_KEX_ECDH_REPLY Nachricht unter Verwendung des kurzlebigen öffentlichen Schlüssels von Server B , des öffentlichen Schlüssels des HPub Server-Hosts und der Signatur auf dem HS Exchange-Hash HPub . Siehe Abb. 4 für weitere Details.


Abb. 2. Generierung des Exchange-Hashs H

Sobald der Client SSH_MSG_KEX_ECDH_REPLY vom Server erhalten hat, hat er alles Notwendige, um das Geheimnis K und den Austausch-Hash H zu berechnen.

Im letzten Teil des Schlüsselaustauschs ruft der Client den öffentlichen SSH_MSG_KEX_ECDH_REPLY (oder das Zertifikat) von SSH_MSG_KEX_ECDH_REPLY und überprüft die Signatur des HS Austausch- SSH_MSG_KEX_ECDH_REPLY , um den Besitz des privaten Schlüssels des Hosts zu bestätigen. Um Angriffe vom Typ "Mann in der Mitte" (MitM) zu verhindern, wird nach Überprüfung der Signatur der öffentliche Schlüssel (oder das Zertifikat) des Hosts mit der lokalen Datenbank bekannter Hosts verglichen. Wenn dieser Schlüssel (oder dieses Zertifikat) nicht vertrauenswürdig ist, wird die Verbindung getrennt.

  Die Authentizität von Host 10.10.10.10 (10.10.10.10) 'kann nicht festgestellt werden.
 Der Fingerabdruck des ECDSA-Schlüssels lautet SHA256: pnPn3SxExHtVGNdzbV0cRzUrtNhqZv + Pwdq / qGQPZO3.
 Sind Sie sicher, dass Sie die Verbindung fortsetzen möchten (Ja / Nein)? 
Der SSH-Client bietet an, den Hostschlüssel der lokalen Datenbank bekannter Hosts hinzuzufügen. Bei OpenSSH ist dies normalerweise ~/.ssh/known_hosts

Eine solche Meldung bedeutet, dass sich der angezeigte Schlüssel nicht in Ihrer lokalen Datenbank bekannter Hosts befindet. Eine gute Möglichkeit, solche Nachrichten zu vermeiden, ist die Verwendung von SSH-Zertifikaten (die von Teleport standardmäßig verwendet werden) anstelle von Schlüsseln. Auf diese Weise können Sie das Zertifikat der Zertifizierungsstelle einfach in einer lokalen Datenbank bekannter Hosts speichern und anschließend alle von dieser Zertifizierungsstelle signierten Hosts überprüfen.


Abb. 3. Generieren einer ECDH-Schlüsselaustauschantwort

Neue Schlüssel


Vor dem Start der Massendatenverschlüsselung blieb die letzte Einschränkung bestehen. Beide Parteien müssen sechs Schlüssel erstellen: zwei für die Verschlüsselung, zwei Initialisierungsvektoren (IV) und zwei für die Integrität. Sie fragen sich vielleicht, warum es so viele zusätzliche Schlüssel gibt? Ist K nicht geheim genug? Nein, nicht genug.

Erstens, warum benötigen wir separate Schlüssel für Verschlüsselung, Integrität und IV? Ein Grund hängt mit der historischen Entwicklung von Protokollen wie TLS und SSH zusammen, nämlich der Aushandlung von kryptografischen Primitiven. In einigen ausgewählten kryptografischen Grundelementen ist die Wiederverwendung von Schlüsseln kein Problem. Wie Henryk Hellstrom jedoch richtig erklärt , können die Folgen katastrophal sein, wenn die Grundelemente falsch ausgewählt werden (z. B. AES-256-CBC für die Verschlüsselung und AES-256-CBC-MAC für die Authentifizierung). Es ist zu beachten, dass Protokollentwickler diese Flexibilität allmählich aufgeben, um Protokolle einfacher und sicherer zu machen.

Warum werden als nächstes Schlüssel jedes Typs verwendet?

Verschlüsselungsschlüssel gewährleisten die Vertraulichkeit der Daten und werden mit einer symmetrischen Verschlüsselung zum Ver- und Entschlüsseln einer Nachricht verwendet.

Integritätsschlüssel werden üblicherweise mit Message Authentication Code (MAC) verwendet, um die Authentizität des Chiffretextes sicherzustellen. Wenn keine Integritätsprüfungen durchgeführt werden, kann ein Angreifer den Chiffretext ändern, der über offene Kanäle übertragen wird, und Sie werden eine gefälschte Nachricht entschlüsseln. Dieses Schema wird normalerweise als Encrypt-then-MAC bezeichnet .

Es ist zu beachten, dass moderne AEAD-Chiffren (authentifizierte Verschlüsselung mit angehängten Daten, wenn ein Teil der Nachricht verschlüsselt wird, ein Teil offen bleibt und die gesamte Nachricht authentifiziert wird) wie aes128-gcm@openssh.com und chacha20-poly1305@openssh.com den abgeleiteten Schlüssel nicht tatsächlich verwenden Integrität für den MAC und Authentifizierung innerhalb ihrer Struktur.

Initialisierungsvektoren (IV) sind normalerweise Zufallszahlen, die als Eingabe für eine symmetrische Chiffre verwendet werden. Ihr Ziel ist es sicherzustellen, dass dieselbe Nachricht, die zweimal verschlüsselt wurde, nicht zu demselben Chiffretext führt. Die Notwendigkeit eines solchen Verfahrens zeigt das berühmte Tux-Pinguin-Bild, das im EZB-Modus (Electronic Code Book) verschlüsselt ist.


Von links nach rechts. (1) Klartext als Bild. (2) Ein Kryptogramm, das durch Verschlüsselung im EZB-Modus erhalten wird. (3) Ein Kryptogramm, das durch Verschlüsselung in einem anderen Modus als der EZB erhalten wird. Das Bild ist eine pseudozufällige Pixelsequenz

Das Verwenden (und Hacken) von IV-Vektoren ist ein interessantes Thema an sich, über das Filippo Walsord schrieb .

Schließlich, warum kommen Schlüssel paarweise? Wie Thomas Pornin feststellte, kann ein Angreifer, wenn nur ein Integritätsschlüssel verwendet wird, den Datensatz, der ihm an den Client gesendet wurde, reproduzieren und er wird ihn als gültig betrachten. Bei gepaarten Integritätsschlüsseln (auf dem Server und dem Client) überprüft der Client die Integrität des Chiffretextes, und dieser Trick funktioniert nicht.

Nachdem wir nun verstanden haben, warum diese Schlüssel benötigt werden, wollen wir sehen, wie sie gemäß dem RFC generiert werden :

  • Vektor IV vom Client zum Server HASH(K || H || «A» || session_id) : HASH(K || H || «A» || session_id)
  • Vektor IV vom Server zum Client HASH(K || H || «B» || session_id) : HASH(K || H || «B» || session_id)
  • Verschlüsselungsschlüssel vom Client zum Server: HASH(K || H || «C» || session_id)
  • Verschlüsselungsschlüssel vom Server zum Client: HASH(K || H || «D» || session_id)
  • Integritätskontrollschlüssel vom Client zum Server: HASH(K || H || «E» || session_id)
  • Integritätskontrollschlüssel vom Server zum Client: HASH(K || H || «F» || session_id)

Hier wird der SHA-Hash-Algorithmus {256, 384 oder 512} verwendet, abhängig vom Schlüsselaustauschalgorithmus und dem Symbol || impliziert Verkettung, d. h. Traktion.

Sobald diese Werte berechnet wurden, senden beide Seiten SSH_MSG_NEWKEYS , um die andere Seite SSH_MSG_NEWKEYS zu informieren, dass der Schlüsselaustausch abgeschlossen ist und alle zukünftigen Kommunikationen mit den oben erstellten neuen Schlüsseln stattfinden sollten.


Abb. 4:. Anfängliche Vektorerzeugung IV. Die Generierung für andere Schlüssel erfolgt nach demselben Schema, wenn A und B durch C, D, E bzw. F ersetzt werden

Fazit


Zu diesem Zeitpunkt einigten sich beide Parteien auf kryptografische Grundelemente, tauschten Geheimnisse aus und generierten Schlüsselmaterial für die ausgewählten Grundelemente. Jetzt kann ein sicherer Kanal zwischen dem Client und dem Server eingerichtet werden, der Vertraulichkeit und Integrität gewährleistet.

Auf diese Weise stellen SSH-Handshakes eine sichere Verbindung zwischen Clients und Servern her.

Source: https://habr.com/ru/post/de474654/


All Articles