Ich versuche, einen einfachen String-zu-SHA1-Konverter in Java zu erstellen, und das habe ich ...
public static String toSHA1(byte[] convertme) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-1");
}
catch(NoSuchAlgorithmException e) {
e.printStackTrace();
}
return new String(md.digest(convertme));
}
Wenn ich es bestanden toSHA1("password".getBytes())
habe, [�a�ɹ??�%l�3~��.
weiß ich, dass es wahrscheinlich eine einfache Codierungskorrektur wie UTF-8 ist, aber könnte mir jemand sagen, was ich tun soll, um das zu bekommen, was ich will, was ist 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
? Oder mache ich das völlig falsch?
SHA1
ohne Bindestrich. Ich weiß nicht, ob dies einen Unterschied macht.getBytes()
, zum Beispiel GebrauchtoSHA1("password".getBytes("UTF-8"))
Antworten:
UPDATE
Sie können den Apache Commons Codec (Version 1.7+) verwenden, um diesen Job für Sie zu erledigen.
Vielen Dank an @ Jon Onstott für diesen Vorschlag.
Alte Antwort
Konvertieren Sie Ihr Byte-Array in einen Hex-String. In Real's How To erfahren Sie, wie .
und (kopiert von Real's How To)
Übrigens erhalten Sie mit Base64 möglicherweise eine kompaktere Darstellung. Apache Commons Codec API 1.4 hat dieses nette Dienstprogramm, um alle Schmerzen zu lindern. siehe hier
quelle
DigestUtils.sha1Hex("my string")
anstatt das Rad neu zu erfinden (obwohl es interessant ist zu wissen, wie man von Hand in Hex konvertiert)?Dies ist meine Lösung, um einen String in sha1 zu konvertieren. Es funktioniert gut in meiner Android App:
quelle
encryptPassword("test")
undecho test|sha1sum
im Linux-Terminal das gleiche Ergebnis ausgegeben werden? Sie tun es nicht.echo test
, wird die Ausgabe einschließlich eines Zeilenumbruchs an weitergeleitetsha1sum
. Wenn Sie eine einfache Zeichenfolge ohne Zeilenumbruch hashen möchten, können Sie verwendenecho -n test | sha1sum
. Der-n
Parameterecho
bewirkt, dass der Zeilenumbruch weggelassen wird.encryptPassword()
Klänge werden zum Speichern von Authentifizierungsdaten verwendet. Beachten Sie, dass Ihre Codierung für Wörterbuchangriffe anfällig ist, da kein Seeding angewendet wird. Überprüfen Sie in Ihrer Sicherheitsumgebung, ob dies ein Problem für Ihre Anwendung ist!Verwenden der Guava Hashing-Klasse :
quelle
SHA-1 (und alle anderen Hashing-Algorithmen) geben Binärdaten zurück. Das bedeutet, dass sie (in Java) a produzieren
byte[]
. Dasbyte
Array ist nicht repräsentieren keine bestimmte Zeichen, welche Mittel Sie nicht einfach in eine verwandeln kannString
wie Sie haben.Wenn Sie eine benötigen
String
, müssen Sie diese so formatieren,byte[]
dass sie als dargestellt werden kannString
(andernfalls behalten Sie einfach diebyte[]
Umgebung bei).Zwei gebräuchliche Arten, beliebige
byte[]
als druckbare Zeichen darzustellen, sind BASE64 oder einfache Hex-Strings (dh jeweilsbyte
durch zwei hexadezimale Ziffern). Es sieht so aus, als würden Sie versuchen, einen Hex-String zu erzeugen.Es gibt noch eine weitere Gefahr: Wenn Sie die SHA-1 eines Java erhalten möchten,
String
müssen Sie dieseString
in einebyte[]
erste konvertieren (da die Eingabe von SHA-1 ebenfalls eine istbyte[]
). Wenn Sie einfach so verwenden,myString.getBytes()
wie Sie es gezeigt haben, wird die Standardcodierung der Plattform verwendet und hängt als solche von der Umgebung ab, in der Sie sie ausführen (z. B. können je nach Sprache / Gebietsschema Ihres Betriebssystems unterschiedliche Daten zurückgegeben werden).Eine bessere Lösung besteht darin, die für die Konvertierung zu verwendende
String
Codierungbyte[]
wie folgt anzugeben :myString.getBytes("UTF-8")
. Die Wahl von UTF-8 (oder einer anderen Codierung, die jedes Unicode-Zeichen darstellen kann) ist hier die sicherste Wahl.quelle
Dies ist eine einfache Lösung, die beim Konvertieren einer Zeichenfolge in ein Hex-Format verwendet werden kann:
quelle
Verwenden Sie einfach die Apache Commons Codec-Bibliothek. Sie haben eine Utility-Klasse namens DigestUtils
Keine Notwendigkeit, auf Details einzugehen.
quelle
String result = DigestUtils.sha1Hex("An input string")
; o)Wie bereits erwähnt, verwenden Sie den Apache Commons Codec. Es wird auch von Spring-Leuten empfohlen (siehe DigestUtils in Spring doc). Z.B:
Würde definitiv nicht die bestbewertete Antwort hier verwenden.
quelle
Es wird nicht richtig gedruckt, da Sie die Base64-Codierung verwenden müssen. Mit Java 8 können Sie mit der Base64- Encoder-Klasse codieren .
Ergebnis
Dies gibt Ihnen Ihre erwartete Ausgabe von
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
quelle
Message Digest (Hash) ist Byte [] in Byte [] out
Ein Message Digest ist als eine Funktion definiert, die ein Rohbyte-Array verwendet und ein Rohbyte-Array (auch bekannt als
byte[]
) zurückgibt . Zum Beispiel hat SHA-1 (Secure Hash Algorithm 1) eine Digest-Größe von 160 Bit oder 20 Byte. Raw-Byte-Arrays können normalerweise nicht als Zeichencodierungen wie UTF-8 interpretiert werden , da nicht jedes Byte in jeder Reihenfolge eine zulässige Codierung ist. Also konvertiere sie in einString
mit:Möglicherweise werden einige unzulässige Sequenzen erstellt oder Codezeiger auf undefinierte Unicode- Zuordnungen:
Binär-zu-Text-Codierung
Hierfür wird die Binär-Text- Codierung verwendet. Bei Hashes wird am häufigsten die HEX-Codierung oder Base16 verwendet . Grundsätzlich kann ein Byte den Wert von
0
bis haben255
(oder-128
bis127
vorzeichenbehaftet) haben, der der HEX-Darstellung von0x00
- entspricht0xFF
. Daher verdoppelt hex die erforderliche Länge der Ausgabe, dh eine 20-Byte-Ausgabe erzeugt eine 40 Zeichen lange Hex-Zeichenfolge, z.Beachten Sie, dass keine Hex-Codierung erforderlich ist. Sie könnten auch so etwas wie base64 verwenden . Hex wird oft bevorzugt, weil es für Menschen leichter lesbar ist und eine definierte Ausgabelänge hat, ohne dass eine Polsterung erforderlich ist.
Sie können ein Byte-Array nur mit JDK-Funktionalität in Hex konvertieren:
Beachten Sie jedoch, dass
BigInteger
das angegebene Byte-Array als Zahl und nicht als Byte-Zeichenfolge interpretiert wird . Das bedeutet, dass führende Nullen nicht ausgegeben werden und die resultierende Zeichenfolge kürzer als 40 Zeichen sein kann.Verwenden von Bibliotheken zum Codieren in HEX
Sie können jetzt eine nicht getestete Byte-zu-Hex-Methode aus dem Stapelüberlauf kopieren und einfügen oder massive Abhängigkeiten wie Guava verwenden .
Um eine Lösung für die meisten bytebezogenen Probleme zu finden, habe ich ein Dienstprogramm implementiert, um diese Fälle zu behandeln: bytes-java (Github)
Um Ihr Nachrichten-Digest-Byte-Array zu konvertieren, können Sie dies einfach tun
oder Sie können einfach die integrierte Hash-Funktion verwenden
quelle
Basis 64 Darstellung von
SHA1
Hash:quelle
Der Grund, warum dies nicht funktioniert, ist, dass Sie
String(md.digest(convertme))
Java beim Aufrufen anweisen, eine Folge verschlüsselter Bytes als Zeichenfolge zu interpretieren. Sie möchten die Bytes in hexadezimale Zeichen konvertieren.quelle
Konvertieren Sie das Byte-Array in eine Hex-Zeichenfolge.
quelle