2017-02-01 7 views
4

Wir verwenden eine Java-Bibliothek namens license3j für die Lizenzverwaltung. Die Bibliothek verwendet asymmetrische Verschlüsselung und stützt sich auf Bouncycastle. Wir erstellen eine Lizenzdatei mit einem einfachen Befehl gpg und überprüfen die Lizenz in unserer Software mit unserem öffentlichen Schlüssel. Bis jetzt hat alles gut funktioniert. ABER: In 1.000 generierten Lizenzen gibt es einen sehr kleinen Bruchteil, der nicht korrekt verifiziert werden kann, obwohl sie tatsächlich gültig sind (ungefähr 5/1000).Signaturlänge nicht korrekt beim Aufruf von PGPOnePassSignature.verify

Was passiert in diesem Fall: Wenn die Lizenz in com.verhas.licensor.License.setLicenseEncoded(InputStream) überprüft werden soll, die org.bouncycastle.openpgp.PGPOnePassSignature.verify(PGPSignature) wirft die folgende Ausnahme:

org.bouncycastle.openpgp.PGPRuntimeOperationException: unable to verify signature: Signature length not correct: got 511 but was expecting 512

Sounds ziemlich dunkel zu mir, nur grundlegende Kenntnisse der Kryptographie mit. Stundenlang googeln, gab mir den Hinweis, dass es etwas über "führende Nullen" gibt. Also wurde in dem gegebenen Beispiel offensichtlich eine führende Null entfernt (wo?), Und die Längen der zu vergleichenden Signaturdaten stimmen nicht überein. Macht Sinn.

Jetzt habe ich keine Ahnung, wo das Problem liegen könnte. Ist es während Erstellung der Lizenzdatei? Im Wesentlichen machen wir nur folgendes:

Welches wird uns die Lizenzdatei geben.

Oder tritt der Fehler während Überprüfung auf? Muss ich irgendeine Bouncycastle-Konfiguration ändern, um das führende Nullenproblem korrekt zu beheben? Ihr FAQ gibt einige Hinweise, aber die License3jsource verwendet offensichtlich nie eine Cipher Instanz, so dass ich total verloren bin, wie man dies in die gegebene API integriert.

Ich bin mir bewusst, dass dies ein ganz besonderes Problem mit einer Bibliothek ist, die offensichtlich nicht sehr gut bekannt ist. Daher schätze ich jede kleine Rückmeldung oder Eingabe.

Antwort

4

Sieht aus wie es ein Fehler in bouncycastle ist, nur in Versionen von Java nach 1,6 angetroffen hat bouncycastle immer die Daten falsch erstellt, aber Java wurde strenger, da 1.7 in den Daten wird es während Überprüfung akzeptieren.

Bouncycastle kann die Signatur nicht auf die richtige Länge auffüllen, wenn es in die Datei serialisiert wird, wenn die ganze Zahl genug führende Nullen hat, dann ist die Byte-Darstellung kleiner.
Java-Versionen 1.7 und höher erwarten, dass RSA-Signaturbytes die gleiche Länge wie der Schlüssel haben.

Bouncycastle konvertiert das RSA-Signatur-Bytearray (das vom Java-RSA-JCE-Provider von Java zurückgegeben wird) in eine ganze Zahl und verwirft Informationen über seine Länge.
Line 263 of the PGPSignatureGenerator zeigt, wo die RSA-Signaturbytes von JCE zurückgegeben und in eine Ganzzahl konvertiert werden.

Diese ganze Zahl wird schließlich unter Verwendung von MPInteger#encode in den Ausgabestrom geschrieben, der nur die Bitlänge des zugrunde liegenden Bigintegers verwendet, um zu bestimmen, wie viele Daten geschrieben werden sollen.

This answer beschreibt mehr darüber, warum Sie diese in etwa 200 Fällen sehen und wie die Version von Java eine Rolle spielt.

+0

Danke Magnus, das hat wirklich geholfen, das Problem zu verstehen! Haben Sie Vorschläge, wie ich dieses Problem mit überschaubarem Aufwand lösen könnte? Beim Durchschreiten der BC-Quelle wird kein Punkt angezeigt, an dem ich mich einhaken könnte. Gibt es Alternativen, die ich nutzen könnte? – qqilihq

+1

Leider scheint es nicht trivial zu sein, es in Bouncycastle zu reparieren, Sie könnten versuchen, einen Fehler in ihrem Issue Tracker auszulösen, aber ich bin nicht sicher, wie viel Erfolg Sie haben werden. Ein Hacky-Workout könnte sein, jede Lizenz zu überprüfen und neu zu generieren, wenn sie fehlschlägt. – Magnus

+0

Eigentlich hatte ich auch die Idee, die Lizenzen neu zu generieren, aber unser Server, auf dem die Lizenzen generiert werden, läuft nicht in einer Java-Umgebung. Es wäre eine riesige Pita, eine JRE nur für die Überprüfung der Lizenzen einzurichten. Ich werde versuchen, ein Problem bei BC darüber anzusprechen. Eine weitere Frage: Gibt es neben BC weitere Krypto-Bibliotheken, oder kann die Überprüfung einer GPG-Signatur heutzutage auch mit Klassen aus der Java-API durchgeführt werden? Immerhin gibt es z.B. eine Klasse 'java.security.Signature'. Die Überprüfungsschritte scheinen überhaupt nicht zu kompliziert zu sein, daher würde ich auch erwägen, diese Funktionalität neu zu schreiben. – qqilihq

Verwandte Themen