2012-06-28 5 views
8

Ich entwickle eine Android-App, und ich brauche java Signature class für die Datenauthentifizierung.SHA256 mit RSA-Signatur gibt verschiedene Ausgaben auf verschiedenen Android-Geräten zurück

Auf jedem Android-Gerät kann ich Daten signieren und ihre Signatur verifizieren. Bei einem bestimmten Datenblock zum Unterschreiben, einem bestimmten Modul, einem bestimmten privaten Exponenten und einem eindeutigen öffentlichen Exponenten sind die Ausgaben meiner Signaturen je nach Gerät unterschiedlich. Ich habe es mit einer Reihe von Geräten versucht, und ich bekomme die gleichen Signaturen für Android 3.2 und 3.2.1, aber ein anderes für ein Android 2.2.x-Gerät.

Ich berechne diese Signatur aus konstanten Feldern, die ich zuvor mit einer KeyFactory mit RSA in einem Java-Projekt generiert. Die Schlüsselgröße ist 2048bit.

Hier ist ein Zitat des Codes, den ich benutze, um Signature und Verification zu invozieren.

public byte[] signData(byte[] data, PrivateKey privateKey) throws ... { 
     Signature signature = Signature.getInstance("SHA256withRSA"); 
     signature.initSign(privateKey); 
     signature.update(data); 
     return signature.sign(); 
} 

public boolean verifyData(byte[] data, byte[] sigBytes, PublicKey publicKey) throws ... { 
     Signature signature = Signature.getInstance("SHA256withRSA"); 
     signature.initVerify(publicKey); 
     signature.update(data); 
     return signature.verify(sigBytes); 
} 

Wenn ich nicht irre, ist die Signatur mit SHA256 mit RSA deterministisch. Wie kann ich ein solches Verhalten erklären? Eine weitere interessante Frage, wie könnte ich diese Arbeit cross-Geräte machen, d. H. Die Signaturen wären gleich, egal welches Gerät ich verwende?

Vielen Dank im Voraus, Franck!

+0

Der Code sieht richtig aus, obwohl das Einfügen der Fehlerhandler kaum erforderlich war. Stellen Sie sicher, dass der Schlüssel und die zu signierenden Daten identisch sind. –

+0

@SevaAlekseyev Ja, ich bin mir sicher, dass alle Eingänge meines Systems gleich sind. Ich habe sie hart als statisches Finale in einer Klasse codiert, die diese Konstanten enthält. Ich habe die konstanten Werte nicht mit Bequemlichkeit verknüpft. – franckysnow

+0

Debug Schritt für Schritt. Berechnen Sie zuerst SHA256-Hashes auf all diesen Plattformen und vergleichen Sie diese. –

Antwort

11

Ja, SHA256withRSA ist vollständig deterministisch.

Theoretisch könnten Sie von einem Fehler (see an example) in einer alten modifizierten BouncyCastle-Bibliotheksversion betroffen sein, die auf einer der Android-Versionen gefunden wurde. Solch ein Fehler könnte eliminiert werden, wenn Sie stattdessen SHA512withRSA verwenden, nun, zumindest der referenzierte wäre.

Bevor Sie jedoch mit der Suche nach dem Hash-Algorithmus beginnen, sollten Sie sich in der Nähe von zu Hause befinden.

Vielleicht haben Sie Ihre Byte-Array durch einen Anruf an String.getBytes erhalten. Dieser Anruf hängt von der standardmäßigen Plattformkodierung ab, die different zwischen Android 2.2 und Android 2.3 ist. Dies bedeutet, dass die Strings in beiden Fällen identisch sind, die Byte-Arrays jedoch möglicherweise nicht.

Zur Codierung unter Kontrolle zu bekommen und Ihren Code Plattform unabhängig machen, geben Sie Codierung als Parameter:

plainText.getBytes("UTF-8") 

dies nicht möglich, gibt es noch ein paar Taktik eine plattformunabhängige Implementierung zu erhalten.

  • warten, bis 2.2 mit der vermutlich Buggy Bibliothek ausstirbt
  • eine bekannte gute Bibliothek (jar) mit der Software verteilen. Wenn dies BouncyCastle wäre, werden Sie Probleme haben, sicherzustellen, dass Ihre und nicht Android Klassen geladen werden. Die Lösung heißt SpongyCastle.
  • spielen mit Ausrichtung/Polsterung. Versuchen Sie, die Nachrichtenlänge in Bytes mit 0,55, 56 oder 63 modulo 64 deckungsgleich zu machen, indem Sie Ihre eigene feste Auffüllung hinzufügen und hoffen, dass eine dieser Optionen beginnt, tragbare Signaturen zu geben. Diese Werte werden ausgewählt, um mit dem äußersten Teil des verdächtigen Algorithmus zu interagieren, der auf 512-Bit-Blöcke aufgefüllt wird.
+0

Vielen Dank für Ihre Antwort Jirka. Ich habe 'SHA256withRSA' in' SHA512withRSA' geändert, aber das Problem wurde nicht behoben. Ich habe immer noch die gleiche Signatur für ein 3.2.1 und 3.2 Android-Geräte, und der Emulator (2.1) bekommt immer noch eine andere Signatur. Die Eingabe ist kein 'String', sondern ein hartcodiertes' byte [] '. Irgendeine andere Idee durch Zufall? – franckysnow

+0

Ich bekomme auch die gleiche Ausgabe wie für 3.2.1 und 3.2 mit einem emulierten 4.0.3 Gerät. – franckysnow

+1

@FranckStudiesCommEng - Antwort erweitert um drei Routen, die ich als nächstes betrachten würde. –

Verwandte Themen