2016-04-26 6 views
2

Ich verwende JSCH 0.1.53 zum Herstellen einer Verbindung zu einem Remote-SSH-Server, der einen 1024-Bit-RSA-Schlüssel verwendet. Wir können uns erfolgreich mit dem Remote-Server verbinden, wenn wir auch einen 1024-Bit-RSA-Schlüssel verwenden, aber als wir stärkere 2048-Bit-Schlüssel erzeugten, konnten wir keine Verbindung mehr herstellen. Wir haben eine Fehlermeldung erhalten, die lautet: "Die Primzahlgröße muss ein Vielfaches von 64 sein und kann nur zwischen 512 und 2048 liegen" und stammt von einem Aufruf von DHGEX.java (Diffie-Hellman Group EXchange).DHGEX fehlgeschlagen mit 2048-Bit-Schlüssel unter Java 8, aber erfolgreich mit 1024-Bit-Schlüssel

Wir führen Java 1.8, und die Fehlermeldung gibt korrekt eine maximale Bitgröße von 2048, so ist das Problem nicht die JCE-Schlüsseleinschränkung von 1024 Bits in Java 1.6 und 1.7. Und wir haben bestätigt, dass sowohl unser privater als auch unser öffentlicher Schlüssel tatsächlich 2048 Bits sind, über openssl rsa -text-noout -in id_rsa und ssh-keygen -lf id_rsa.pub.

Da alles in Ordnung auf unserer Seite sah, begann ich Debug-Linien zum JSch Code hinzufügen und die JAR neu zu kompilieren, und ich war schließlich in der Lage zu bestimmen, dass das Modul in der Tat war lange 2047 Bits während des Schlüsselaustauschs zu uns geführt wird . Jetzt bedeutet 2047 Bits inhärent nicht, dass Sie keinen 2048-Bit-Schlüssel erzeugt haben, oder dass er weniger stark ist als ein Schlüssel, der tatsächlich 2048 Bits enthält, es bedeutet nur, dass Sie zufällig zwei Primzahlen bekommen haben, die sich multiplizieren zu etwas, dessen erstes Bit eine 0 war. Also ist es das erwartete Verhalten (zeitweise) und die JCE-Prüfung sollte wahrscheinlich sein (n% 64 == 0 || n% 64 == 63). Aber JCE ist ein Verfechter auf dem Punkt, so lehnt es diesen Schlüssel ab, weil er nicht von einer Länge ist, die er als gültig betrachtet.

Darauf basierend dachte ich, ich hätte das Problem gefunden: Der Remote-Server hatte einen 2048-Bit-Schlüssel generiert, der nur 2047 Bit enthielt, also mussten sie nur einen neuen generieren (und es so lange machen) eine, die wirklich 2048 Bits war). Aber als ich ihre Administratoren danach fragte, bestanden sie darauf, dass sie einen 1024-Bit-Schlüssel verwendeten, und das ist tatsächlich, was Sie in der Datei "known_hosts" erhalten, wenn Sie mit SSH fortfahren. Das scheint also nicht die Ursache zu sein.

Also fing ich an, den Inhalt des Puffers zu protokollieren, der enthielt, was sie uns schickten und die p- und g-Werte (Modul und Gruppe) herausholte, und ich entdeckte das innerhalb weniger Tage innerhalb weniger Tage Es gab 33 verschiedene Moduluswerte, und alle unterschieden sich nur durch die letzten paar Zeichen, wenn sie entweder in Basis 64 oder Basis 10 kodiert waren. Moduli-Werte wurden wiederverwendet, manchmal nur einmal und manchmal ein Dutzend Mal, aber es gab viele verschiedene Werte Daher werden die Schlüssel weder für die einmalige Verwendung generiert noch einmal generiert und für immer wiederverwendet.

Ist dies (mit dem Server senden viele verschiedene Schlüssel, die sehr eng sind numerisch, mit einigen Wiederverwendung, aber viele eindeutige Werte) erwartet Verhalten unter allen Bedingungen, und insbesondere ist dieses erwartete Verhalten, wenn der Client einen 2048-Bit-Schlüssel verwendet Der Server verwendet einen 1024-Bit-Schlüssel? Ich weiß nichts über Diffie-Hellman-Gruppenaustausch außer dem, was ich gelesen habe, seit ich in der letzten Woche angefangen habe zu recherchieren, also funktioniert es vielleicht genauso, aber es scheint mir seltsam zu sein.

Gibt der SSH-Standard auch etwas darüber aus, wie Schlüssel in solchen Fällen generiert werden sollen? Ich habe noch nicht herausgefunden, welchen SSH-Server die Gegenseite benutzt (ich vermute OpenSSH, weiß aber nicht genau und weiß nicht, welche Version), aber ich bin zuversichtlich, dass es einen Standard geben könnte, der das zwingt Verwendung von Schlüsseln, die die gleiche Größe haben wie angefordert (zwischen 1^(n-1) und 1^n - 1), und dass der entfernte Server eine Option haben könnte, dies oder das zu tun, kann ich einen Fehler gegen sie einreichen um sie dazu zu bringen, das Verhalten zu ändern. Ich werde wahrscheinlich auch einen Bug gegen das JDK einreichen, um Schlüssel von n-1 Bits zu erlauben, mit 0-Padding für das erste Bit.

Jede Anleitung, die jeder geben kann, würde sehr geschätzt werden.

Ich habe auch geschrieben, diese Frage an die JSch Mailingliste: https://sourceforge.net/p/jsch/mailman/message/35042955/

UPDATE:

Nach einer weiteren Lesung, ich glaube, dass Diffie-Hellman Forward Secrecy Charakteristik bedeutet, dass verschiedene Primzahlen (oft aus ein vorgenerierter Satz, der irgendwo gespeichert wird wie/etc/ssl/moduli) würde für jede Sitzung benutzt werden (source: https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange#Forward_secrecy) und dass die Primzahl nicht wirklich der RSA-Schlüssel ist (source: https://stackoverflow.com/a/23346185/1247705), also die Tatsache, dass viele verschiedene p Werte sind nicht länger ein Anliegen. Ich bin immer noch überrascht, dass sie so nah am Wert sind, aber vielleicht wird das auch erwartet.

Die Gegenseite verwendet Solaris SSH 1.1.4 (das, wie ich es verstehe, auf OpenSSH basiert) als SSH-Daemon. Wird erwartet, dass dieser Daemon als Teil des Diffie-Hellman-Schlüsselaustauschs 2047-Bit-Primzahlen übergibt, und gibt es etwas, das getan werden kann, um stattdessen 2048-Bit-Primzahlen zu senden?

+0

Haben Sie die [Unlimited Strength Policy for Java 8] (http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html) Dateien installiert? –

+0

Ich nicht, und ich habe nichts gesehen, das mich glauben lässt, dass das notwendig ist. Mit einem JUnit-Test kann ich den Code ausführen, der die Ausnahme auslöst (indem man p und g auf ein com.jcraft.jsch.jce.DH-Objekt legt und dann getE() darauf aufruft) mit unserem 2048-Bit-Schlüssel. und es läuft ohne Problem, aber es schlägt fehl, wenn ich mit einem 2047-Bit-Schlüssel vom Remote-Server erhalten. Wenn die Richtlinie für unbegrenzte Stärke benötigt würde, würde ich erwarten, dass dieser Aufruf für unseren 2048-Bit-Schlüssel fehlschlägt. Aber wenn Sie Informationen haben, die anzeigen, dass es in meinem spezifischen Szenario helfen würde, teilen Sie es bitte mit. – Tim

+1

Wie Sie aktualisiert haben, hat DHhex-Modul (eine Primzahl) nichts mit einem RSA-Modul zu tun (ein Produkt von zwei Primzahlen). Java JCE wendet offensichtlich auf DH-Parameter die DSA-Einschränkung für die Gruppengröße an, da es seine DSS-Parametergenerierungslogik für DH-Parameter (wieder) verwendet, aber es gibt keinen guten Grund, diese Einschränkung auf extern generierte/empfangene Parameter anzuwenden. OpenSSH 'sshd' verwendet definitiv DHgex Module aus einer Datei; wenn * generated * mit 'ssh-keygen' diese Datei enthält eine Reihe von Primzahlen aus einem begrenzten Bereich (hohe Bits gleich) und unerklärlicherweise ein Bit kleiner als angegeben .... –

Antwort

2

Wir setzten ähnliche Symptome mit:

Security.insertProviderAt(new BouncyCastleProvider(), 1) 

wir wurden mit JSch 0.1.54 und sah:

java.security.InvalidAlgorithmParameterException: DH-Schlüsselgröße von 64 mehrfach sein muss, und kann nur im Bereich von 512 bis 4096 (inklusive). Die spezifische Schlüsselgröße 2047 wird nicht unterstützt

möglicherweise verwandt ist JDK-8164963: InvalidAlgorithmParameterException prime size issue after JDK upgrade with JSCH libraries

+0

Das sind gute Informationen, und es ist interessant zu sehen, dass der Fehler, auf den Sie verwiesen haben, mit dieser Frage verknüpft ist. Die OpenJDK-Leute scheinen entschieden zu haben, dass dies nicht ihr Problem ist (und was sie geschrieben haben, impliziert, dass sie denken, dass es das OpenSSH-Problem ist). – Tim

0

ich um dieses Problem arbeiten schließlich durch die Schlüsselaustauschalgorithmen zu deaktivieren, die eine Variante des Diffie-Hellman-Gruppe Schlüsselaustausch verwendet. @Brian Low scheint mit BouncyCastle anstelle des integrierten Sicherheitsproviders des JDK herumgearbeitet zu haben.

Ich betrachte beide als Problemumgehungen, die das zugrunde liegende Problem nicht lösen (anscheinend ein Fehler im JDK für die von ihnen akzeptierten Schlüsselgrößen oder in OpenSSH für die von ihnen generierten Schlüsselgrößen), aber keines davon Ich und mein Projekt kümmerten sich nicht darum, Zeit und Geld damit zu verschwenden, den einen oder anderen dazu zu zwingen, das Problem in den Griff zu bekommen.

Verwandte Themen