6. Binary Packet Protocol (Binäres Paketprotokoll)
6. Binary Packet Protocol (Binäres Paketprotokoll)
Jedes Paket hat folgendes Format:
uint32 packet_length
byte padding_length
byte[n1] payload; n1 = packet_length - padding_length - 1
byte[n2] random padding; n2 = padding_length
byte[m] mac (Message Authentication Code - MAC); m = mac_length
packet_length
Länge des Pakets in Bytes, ohne 'mac' und ohne das Feld
'packet_length' selbst.
padding_length
Länge von 'random padding' (Bytes).
payload
Nutzinhalt des Pakets. Wurde Kompression ausgehandelt, ist
dieses Feld komprimiert. Anfangs MUSS die Kompression "none" sein.
random padding
Padding beliebiger Länge, sodass die Gesamtlänge von
(packet_length || padding_length || payload || random padding)
ein Vielfaches der Chiffre-Blockgröße oder 8, je nachdem welcher
Wert größer ist, ist. Es MUSS mindestens vier Bytes Padding geben.
Das Padding SOLLTE aus Zufallsbytes bestehen. Die maximale
Paddingmenge beträgt 255 Bytes.
mac
Message Authentication Code. Wurde Nachrichtenauthentifizierung
ausgehandelt, enthält dieses Feld die MAC-Bytes. Anfangs MUSS
der MAC-Algorithmus "none" sein.
Beachten Sie, dass die Länge der Verkettung von 'packet_length', 'padding_length', 'payload' und 'random padding' ein Vielfaches der Chiffre-Blockgröße oder 8, je nachdem welcher Wert größer ist, sein MUSS. Diese Einschränkung MUSS auch bei Stromchiffren (stream ciphers) durchgesetzt werden. Beachten Sie, dass das Feld 'packet_length' ebenfalls verschlüsselt ist und seine Verarbeitung beim Senden oder Empfangen von Paketen besondere Sorgfalt erfordert. Beachten Sie außerdem, dass das Einfügen variabler Mengen von 'random padding' dabei helfen kann, Verkehrsanalyse (traffic analysis) zu erschweren.
Die Mindestgröße eines Pakets beträgt 16 (oder die Chiffre-Blockgröße, je nachdem welcher Wert größer ist) Bytes (plus 'mac'). Implementierungen SOLLTEN die Länge entschlüsseln, nachdem die ersten 8 (oder Chiffre-Blockgröße, je nachdem welcher Wert größer ist) Bytes eines Pakets empfangen wurden.
6.1. Maximum Packet Length (Maximale Paketlänge)
Alle Implementierungen MÜSSEN Pakete mit einer unkomprimierten Nutzlastlänge (uncompressed payload length) von höchstens 32768 Bytes und einer Gesamtpaketgröße von höchstens 35000 Bytes (einschließlich 'packet_length', 'padding_length', 'payload', 'random padding' und 'mac') verarbeiten können. Das Maximum von 35000 Bytes ist ein willkürlich gewählter Wert, der größer ist als die oben genannte unkomprimierte Länge. Implementierungen SOLLTEN längere Pakete unterstützen, wo dies erforderlich sein kann. Möchte eine Implementierung beispielsweise eine sehr große Anzahl von Zertifikaten senden, KÖNNEN größere Pakete gesendet werden, wenn die Identifikationszeichenfolge anzeigt, dass die Gegenseite sie verarbeiten kann. Implementierungen SOLLTEN jedoch prüfen, dass die Paketlänge plausibel ist, damit die Implementierung Denial-of-Service- und/oder Pufferüberlaufangriffe vermeiden kann.
6.2. Compression (Kompression)
Wurde Kompression ausgehandelt, wird das Feld 'payload' (und nur dieses) mit dem ausgehandelten Algorithmus komprimiert. Die Felder 'packet_length' und 'mac' werden aus der komprimierten Nutzlast berechnet. Die Verschlüsselung erfolgt nach der Kompression.
Kompression KANN zustandsbehaftend (stateful) sein, abhängig von der Methode. Kompression MUSS für jede Richtung unabhängig sein, und Implementierungen MÜSSEN die unabhängige Wahl des Algorithmus je Richtung erlauben. In der Praxis wird jedoch EMPFOHLEN, in beiden Richtungen dieselbe Kompressionsmethode zu verwenden.
Folgende Kompressionsmethoden sind derzeit definiert:
none REQUIRED keine Kompression
zlib OPTIONAL ZLIB-(LZ77-)Kompression
Die Kompression „zlib“ ist in [RFC1950] und [RFC1951] beschrieben. Der Kompressionskontext wird nach jedem Schlüsselaustausch initialisiert und von Paket zu Paket weitergegeben, wobei am Ende jedes Pakets nur ein partieller Flush durchgeführt wird. Ein partieller Flush bedeutet, dass der aktuelle komprimierte Block beendet wird und alle Daten ausgegeben werden. Ist der aktuelle Block kein gespeicherter Block (stored block), werden nach dem aktuellen Block ein oder mehrere leere Blöcke angefügt, sodass vom Beginn des End-of-Block-Codes des aktuellen Blocks bis zum Ende der Paketnutzlast mindestens 8 Bits vorhanden sind.
Weitere Methoden können wie in [SSH-ARCH] und [SSH-NUMBERS] spezifiziert definiert werden.
6.3. Encryption (Verschlüsselung)
Ein Verschlüsselungsalgorithmus und ein Schlüssel werden während des Schlüsselaustauschs ausgehandelt. Wenn Verschlüsselung aktiv ist, MÜSSEN die Felder Paketlänge, Padding-Länge, Nutzlast und Padding jedes Pakets mit dem angegebenen Algorithmus verschlüsselt werden.
Die verschlüsselten Daten aller in eine Richtung gesendeten Pakete SOLLTEN als ein einzelner Datenstrom betrachtet werden. Beispielsweise SOLLTEN Initialisierungsvektoren (initialization vectors) vom Ende eines Pakets zum Beginn des nächsten übernommen werden. Alle Chiffren SOLLTEN Schlüssel mit einer effektiven Schlüssellänge von 128 Bits oder mehr verwenden.
Die Chiffren in jeder Richtung MÜSSEN unabhängig voneinander laufen. Implementierungen MÜSSEN erlauben, den Algorithmus je Richtung unabhängig zu wählen, wenn die lokale Richtlinie mehrere Algorithmen zulässt. In der Praxis wird jedoch EMPFOHLEN, in beiden Richtungen denselben Algorithmus zu verwenden.
Folgende Chiffren sind derzeit definiert:
3des-cbc REQUIRED Dreifach-3DES im CBC-Modus
blowfish-cbc OPTIONAL Blowfish im CBC-Modus
twofish256-cbc OPTIONAL Twofish im CBC-Modus,
mit 256-Bit-Schlüssel
twofish-cbc OPTIONAL Alias für "twofish256-cbc"
(aus historischen Gründen
beibehalten)
twofish192-cbc OPTIONAL Twofish mit 192-Bit-Schlüssel
twofish128-cbc OPTIONAL Twofish mit 128-Bit-Schlüssel
aes256-cbc OPTIONAL AES im CBC-Modus,
mit 256-Bit-Schlüssel
aes192-cbc OPTIONAL AES mit 192-Bit-Schlüssel
aes128-cbc RECOMMENDED AES mit 128-Bit-Schlüssel
serpent256-cbc OPTIONAL Serpent im CBC-Modus mit
256-Bit-Schlüssel
serpent192-cbc OPTIONAL Serpent mit 192-Bit-Schlüssel
serpent128-cbc OPTIONAL Serpent mit 128-Bit-Schlüssel
arcfour OPTIONAL ARCFOUR-Stromchiffre
mit 128-Bit-Schlüssel
idea-cbc OPTIONAL IDEA im CBC-Modus
cast128-cbc OPTIONAL CAST-128 im CBC-Modus
none OPTIONAL keine Verschlüsselung;
NICHT EMPFOHLEN
Die Chiffre „3des-cbc“ ist Dreifach-DES (encrypt-decrypt-encrypt), wobei die ersten 8 Bytes des Schlüssels für die erste Verschlüsselung, die nächsten 8 Bytes für die Entschlüsselung und die folgenden 8 Bytes für die finale Verschlüsselung verwendet werden. Es werden 24 Bytes Schlüsselmaterial benötigt (davon tatsächlich 168 Bits genutzt). Für den CBC-Modus MUSS äußere Verkettung (outer chaining) verwendet werden (d. h. es gibt nur einen Initialisierungsvektor). Dies ist eine Blockchiffre mit 8-Byte-Blöcken. Der Algorithmus ist in [FIPS-46-3] definiert. Da dieser Algorithmus nur eine effektive Schlüssellänge von 112 Bits hat ([SCHNEIER]), erfüllt er nicht die Vorgabe, dass SSH-Verschlüsselungsalgorithmen Schlüssel von 128 Bits oder mehr verwenden sollen. Er ist dennoch aus historischen Gründen ERFORDERLICH: im Wesentlichen unterstützen zum Zeitpunkt der Abfassung alle bekannten Implementierungen diesen Algorithmus, und er wird häufig genutzt, weil er der grundlegende interoperable Algorithmus ist. Es wird erwartet, dass zu einem späteren Zeitpunkt ein Algorithmus mit besserer Stärke so verbreitet wird, dass die Nutzung von „3des-cbc“ durch eine weitere STANDARDS ACTION abgelöst wird.
Die Chiffre „blowfish-cbc“ ist Blowfish im CBC-Modus mit 128-Bit-Schlüsseln [SCHNEIER]. Dies ist eine Blockchiffre mit 8-Byte-Blöcken.
Die Chiffre „twofish-cbc“ oder „twofish256-cbc“ ist Twofish im CBC-Modus mit 256-Bit-Schlüsseln wie in [TWOFISH] beschrieben. Dies ist eine Blockchiffre mit 16-Byte-Blöcken.
Die Chiffre „twofish192-cbc“ entspricht der obigen, jedoch mit 192-Bit-Schlüssel.
Die Chiffre „twofish128-cbc“ entspricht der obigen, jedoch mit 128-Bit-Schlüssel.
Die Chiffre „aes256-cbc“ ist AES (Advanced Encryption Standard) [FIPS-197] im CBC-Modus. Diese Variante verwendet einen 256-Bit-Schlüssel.
Die Chiffre „aes192-cbc“ entspricht der obigen, jedoch mit 192-Bit-Schlüssel.
Die Chiffre „aes128-cbc“ entspricht der obigen, jedoch mit 128-Bit-Schlüssel.
Die Chiffre „serpent256-cbc“ ist Serpent im CBC-Modus mit 256-Bit-Schlüssel wie in der Serpent-AES-Einreichung beschrieben.
Die Chiffre „serpent192-cbc“ entspricht der obigen, jedoch mit 192-Bit-Schlüssel.
Die Chiffre „serpent128-cbc“ entspricht der obigen, jedoch mit 128-Bit-Schlüssel.
Die Chiffre „arcfour“ ist die Arcfour-Stromchiffre mit 128-Bit-Schlüsseln. Die Arcfour-Chiffre gilt als kompatibel mit der RC4-Chiffre [SCHNEIER]. Arcfour (und RC4) haben Probleme mit schwachen Schlüsseln und sollten mit Vorsicht eingesetzt werden.
Die Chiffre „idea-cbc“ ist die IDEA-Chiffre im CBC-Modus [SCHNEIER].
Die Chiffre „cast128-cbc“ ist die CAST-128-Chiffre im CBC-Modus mit 128-Bit-Schlüssel [RFC2144].
Der Algorithmus „none“ legt fest, dass keine Verschlüsselung erfolgt. Diese Methode bietet keinen Vertraulichkeitsschutz und ist NICHT EMPFOHLEN. Einige Funktionen (z. B. Passwortauthentifizierung) können aus Sicherheitsgründen deaktiviert werden, wenn diese Chiffre gewählt wird.
Weitere Methoden können wie in [SSH-ARCH] und [SSH-NUMBERS] spezifiziert definiert werden.
6.4. Data Integrity (Datenintegrität)
Die Datenintegrität wird geschützt, indem jedem Paket ein MAC beigefügt wird, der aus einem gemeinsamen Geheimnis (shared secret), der Paketsequenznummer (packet sequence number) und dem Paketinhalt berechnet wird.
Der Nachrichtenauthentifizierungsalgorithmus und der Schlüssel werden während des Schlüsselaustauschs ausgehandelt. Anfangs ist kein MAC aktiv, und seine Länge MUSS null sein. Nach dem Schlüsselaustausch wird der 'mac' für den gewählten MAC-Algorithmus vor der Verschlüsselung aus der Verkettung der Paketdaten berechnet:
mac = MAC(key, sequence_number || unencrypted_packet)
Dabei ist unencrypted_packet das gesamte Paket ohne 'mac' (die Längenfelder, 'payload' und 'random padding'), und sequence_number ist eine implizite Paketsequenznummer als uint32. Die sequence_number wird für das erste Paket mit null initialisiert und nach jedem Paket erhöht (unabhängig davon, ob Verschlüsselung oder MAC verwendet wird). Sie wird nie zurückgesetzt, auch wenn Schlüssel/Algorithmen später neu ausgehandelt werden. Sie läuft nach jeweils 2^32 Paketen über. Die Paketsequenznummer selbst ist im über die Leitung gesendeten Paket nicht enthalten.
Die MAC-Algorithmen für jede Richtung MÜSSEN unabhängig laufen, und Implementierungen MÜSSEN die unabhängige Wahl des Algorithmus für beide Richtungen erlauben. In der Praxis wird jedoch EMPFOHLEN, in beiden Richtungen denselben Algorithmus zu verwenden.
Der aus dem MAC-Algorithmus resultierende Wert von 'mac' MUSS unverschlüsselt als letzter Teil des Pakets übertragen werden. Die Anzahl der 'mac'-Bytes hängt vom gewählten Algorithmus ab.
Folgende MAC-Algorithmen sind derzeit definiert:
hmac-sha1 REQUIRED HMAC-SHA1 (Digestlänge = Schlüssel-
länge = 20)
hmac-sha1-96 RECOMMENDED erste 96 Bits von HMAC-SHA1 (Digest-
länge = 12, Schlüssellänge = 20)
hmac-md5 OPTIONAL HMAC-MD5 (Digestlänge = Schlüssel-
länge = 16)
hmac-md5-96 OPTIONAL erste 96 Bits von HMAC-MD5 (Digest-
länge = 12, Schlüssellänge = 16)
none OPTIONAL kein MAC; NICHT EMPFOHLEN
Die „hmac-“-Algorithmen sind in [RFC2104] beschrieben. Die „-n“-MACs verwenden nur die ersten n Bits des Ergebnisses.
SHA-1 ist in [FIPS-180-2] und MD5 in [RFC1321] beschrieben.
Weitere Methoden können wie in [SSH-ARCH] und [SSH-NUMBERS] spezifiziert definiert werden.
6.5. Key Exchange Methods (Schlüsselaustauschmethoden)
Die Schlüsselaustauschmethode legt fest, wie Einmal-Sitzungsschlüssel (one-time session keys) für Verschlüsselung und Authentifizierung erzeugt werden und wie die Serverauthentifizierung erfolgt.
Zwei ERFORDERLICHE Schlüsselaustauschmethoden wurden definiert:
diffie-hellman-group1-sha1 REQUIRED
diffie-hellman-group14-sha1 REQUIRED
Diese Methoden sind in Abschnitt 8 beschrieben.
Weitere Methoden können wie in [SSH-NUMBERS] spezifiziert definiert werden. Der Name „diffie-hellman-group1-sha1“ wird für eine Schlüsselaustauschmethode verwendet, die eine Oakley-Gruppe nutzt, wie in [RFC2409] definiert. SSH führt einen eigenen Gruppenkennraum (group identifier space), der logisch von Oakley [RFC2412] und IKE getrennt ist; für eine zusätzliche Gruppe hat die Arbeitsgruppe jedoch die in [RFC3526] vergebene Nummer übernommen und verwendet diffie-hellman-group14-sha1 als Namen der zweiten definierten Gruppe. Implementierungen sollten diese Namen als undurchsichtige Bezeichner behandeln und keine Beziehung zwischen den von SSH genutzten Gruppen und den für IKE definierten Gruppen annehmen.
6.6. Public Key Algorithms (Public-Key-Algorithmen)
Dieses Protokoll ist so konzipiert, dass es mit nahezu jedem Public-Key-Format, jeder Kodierung und jedem Algorithmus (Signatur und/oder Verschlüsselung) arbeiten kann.
Mehrere Aspekte definieren einen Public-Key-Typ:
-
Schlüsselformat (key format): Kodierung des Schlüssels und Darstellung von Zertifikaten. Die Schlüssel-Blobs in diesem Protokoll KÖNNEN neben Schlüsseln auch Zertifikate enthalten.
-
Signatur- und/oder Verschlüsselungsalgorithmen. Einige Schlüsseltypen unterstützen möglicherweise weder Signierung noch Verschlüsselung. Die Schlüsselnutzung kann auch durch Richtlinienaussagen (z. B. in Zertifikaten) eingeschränkt sein. In diesem Fall SOLLTEN für die verschiedenen Richtlinienalternativen unterschiedliche Schlüsseltypen definiert werden.
-
Kodierung von Signaturen und/oder verschlüsselten Daten. Dazu gehören unter anderem Padding, Byte-Reihenfolge und Datenformate.
Folgende Public-Key- und/oder Zertifikatsformate sind derzeit definiert:
ssh-dss REQUIRED sign Roher DSS-Schlüssel
ssh-rsa RECOMMENDED sign Roher RSA-Schlüssel
pgp-sign-rsa OPTIONAL sign OpenPGP-Zertifikate (RSA-Schlüssel)
pgp-sign-dss OPTIONAL sign OpenPGP-Zertifikate (DSS-Schlüssel)
Weitere Schlüsseltypen können wie in [SSH-ARCH] und [SSH-NUMBERS] spezifiziert definiert werden.
Der Schlüsseltyp MUSS stets explizit bekannt sein (aus Algorithmusverhandlung oder einer anderen Quelle). Er ist normalerweise nicht im Schlüssel-Blob enthalten.
Zertifikate und öffentliche Schlüssel werden wie folgt kodiert:
string Zertifikats- oder Public-Key-Formatkennung
byte[n] Schlüssel-/Zertifikatsdaten
Der Zertifikatsteil kann eine Zeichenfolge der Länge null sein, ein öffentlicher Schlüssel ist jedoch erforderlich. Dies ist der öffentliche Schlüssel, der für die Authentifizierung verwendet wird. Die in dem Zertifikats-Blob enthaltene Zertifikatssequenz kann zur Autorisierung dienen.
Public-Key-/Zertifikatsformate, die keinen Signaturformatkenner ausdrücklich angeben, MÜSSEN den Public-Key-/Zertifikatsformatkenner als Signaturkenner verwenden.
Signaturen werden wie folgt kodiert:
string Signaturformatkenner (wie vom Public-Key-/
Zertifikatsformat vorgegeben)
byte[n] Signatur-Blob in format-spezifischer Kodierung.
Das Schlüsselformat „ssh-dss“ hat folgende spezifische Kodierung:
string "ssh-dss"
mpint p
mpint q
mpint g
mpint y
Hier bilden die Parameter 'p', 'q', 'g' und 'y' den Signaturschlüssel-Blob.
Signieren und Verifizieren mit diesem Schlüsselformat erfolgt gemäß dem Digital Signature Standard [FIPS-186-2] unter Verwendung des SHA-1-Hashs [FIPS-180-2].
Die resultierende Signatur wird wie folgt kodiert:
string "ssh-dss"
string dss_signature_blob
Der Wert für 'dss_signature_blob' ist als Zeichenfolge kodiert, die r gefolgt von s enthält (160-Bit-Ganzzahlen, ohne Längen oder Padding, vorzeichenlos, in Netzwerk-Byte-Reihenfolge).
Das Schlüsselformat „ssh-rsa“ hat folgende spezifische Kodierung:
string "ssh-rsa"
mpint e
mpint n
Hier bilden die Parameter 'e' und 'n' den Signaturschlüssel-Blob.
Signieren und Verifizieren mit diesem Schlüsselformat erfolgt gemäß dem RSASSA-PKCS1-v1_5-Schema in [RFC3447] unter Verwendung des SHA-1-Hashs.
Die resultierende Signatur wird wie folgt kodiert:
string "ssh-rsa"
string rsa_signature_blob
Der Wert für 'rsa_signature_blob' ist als Zeichenfolge kodiert, die s enthält (eine Ganzzahl ohne Längen oder Padding, vorzeichenlos, in Netzwerk-Byte-Reihenfolge).
Die Methode „pgp-sign-rsa“ bedeutet, dass Zertifikate, öffentlicher Schlüssel und Signatur im OpenPGP-kompatiblen Binärformat ([RFC2440]) vorliegen. Die Methode kennzeichnet einen RSA-Schlüssel.
„pgp-sign-dss“ entspricht dem obigen, kennzeichnet jedoch einen DSS-Schlüssel.