Wie kann man einen String mit sha256 in Java hashen?


Antworten:


307

SHA-256 ist keine "Codierung" - es ist ein Einweg-Hash.

Sie würden den String grundsätzlich in Bytes konvertieren (z. B. using text.getBytes(StandardCharsets.UTF_8)) und dann die Bytes hashen. Beachten Sie, dass das Ergebnis des Hashs auch beliebige Binärdaten sind. Wenn Sie dies in einer Zeichenfolge darstellen möchten, sollten Sie base64 oder hex verwenden. Versuchen Sie nicht , den String(byte[], String)Konstruktor zu verwenden.

z.B

MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(text.getBytes(StandardCharsets.UTF_8));

18
"SHA-256 ist keine Kodierung" ist absolut richtig, aber ich muss sagen, ich ziehe den Titel der aktuellen Frage dem "Verschlüsseln mit sha" vor (viele scheinen zu glauben, dass es sich um eine Verschlüsselung handelt). Vielleicht sollten wir es als Codierung behandeln, anstatt etwas mit Kryptografie zu tun zu haben, da dies in der Praxis näher an der Verwendung liegt.
Luc

5
@Luc: Nun , es ist ein kryptographischer Hash, also denke ich nicht , dass es unvernünftig ist , zu sagen , es ist etwas mit Kryptographie ... Verschlüsselung und Kryptographie zu tun hat , sind nicht austauschbar ...
Jon Skeet

8
Hinweis: Es ist eine gute Idee, StandardCharsets.UTF_8 anstelle des "UTF-8"Literal in Java 7+ zu verwenden: Eine aktivierte Ausnahme ist weniger wichtig.
Kryger

3
Warum sollten Sie den Konstruktor String (byte [], String) vermeiden, wenn Sie mit dem Hash-Ergebnis arbeiten?
Isaac van Bakel

5
@IsaacvanBakel: Weil ein Hash kein codierter Text ist. Es sind beliebige Binärdaten.
Jon Skeet

172

Ich denke, dass die einfachste Lösung die Verwendung von Apache Common Codec ist :

String sha256hex = org.apache.commons.codec.digest.DigestUtils.sha256Hex(stringText);   

1
Beste Antwort, einfach zu bedienen, sauber. Danke dir!
fl0w

99

Eine weitere Alternative ist Guava mit einer benutzerfreundlichen Suite von Hashing- Dienstprogrammen. Um beispielsweise einen String mit SHA256 als Hex-String zu hashen, gehen Sie einfach wie folgt vor:

final String hashed = Hashing.sha256()
        .hashString("your input", StandardCharsets.UTF_8)
        .toString();

85

Vollständiges Beispiel für einen Hash als weiteren String.

public static String sha256(String base) {
    try{
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(base.getBytes("UTF-8"));
        StringBuffer hexString = new StringBuffer();

        for (int i = 0; i < hash.length; i++) {
            String hex = Integer.toHexString(0xff & hash[i]);
            if(hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }

        return hexString.toString();
    } catch(Exception ex){
       throw new RuntimeException(ex);
    }
}

7
Um Jons Ergebnisse als Hex zu codieren, sollten Sie eine vorhandene Bibliothek wie Apache Commons verwenden, anstatt Ihre eigene zu rollen.
Leigh

1
Warum StringBuffer? (kein stringBuilder)? und vielleicht wäre es besser, die Standardgröße des Stringbuilders festzulegen?
Bogdan

36
@Leigh: Einige Leute möchten keine ganze lib-Abhängigkeit hinzufügen, nur weil sie eine einzige Funktion davon benötigen, so dass es manchmal eine gute Idee ist, eine eigene zu rollen.
Chris

4
@ Chris - Stimmt. Deshalb habe ich "erwägen", es zu verwenden ;-) Bestehende Bibliotheken können Bulk hinzufügen. Auf der anderen Seite sind sie normalerweise besser getestet als selbst gesponnener Code und sparen natürlich Zeit. Aber es gibt keine einheitliche Antwort für alle.
Leigh

1
Sie können auch den Quellcode aus der Bibliothek lesen und den Code kopieren!
Olav Grønås Gjerde

47

Wenn Sie Java 8 verwenden, können Sie das byte[]durch Codieren codieren

MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(text.getBytes(StandardCharsets.UTF_8));
String encoded = Base64.getEncoder().encodeToString(hash);

1
Dieser Weg ist bequem für mich. Sie sollten jedoch den folgenden Base64.encodeToString (Hash, Base64.DEFAULT) verwenden.
Motassem Jalal

@MotassemJalal Base64.DEFAULT ist in der neuesten Version von Java8 nicht verfügbar. Ich verwende derzeit jdk1.8.0_144. Können Sie mir bitte mitteilen, wie Sie es erstellt haben?
Rajadilipkolli

2
@rajadilipkolli Ich denke, es ist die Android-Implementierung: developer.android.com/reference/android/util/Base64
dbm

12
import java.security.MessageDigest;

public class CodeSnippets {

 public static String getSha256(String value) {
    try{
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(value.getBytes());
        return bytesToHex(md.digest());
    } catch(Exception ex){
        throw new RuntimeException(ex);
    }
 }
 private static String bytesToHex(byte[] bytes) {
    StringBuffer result = new StringBuffer();
    for (byte b : bytes) result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
    return result.toString();
 }
}

Was bringt es, einen Bytewert bitweise zu & -ing 0xff? Es gibt nichts, oder?
Yktoo

2
@yktoo: Es konvertiert es in eine positive Ganzzahl (Bytes sind leider in Java signiert) stackoverflow.com/questions/11380062/…
leonbloy

StringBuffer kann durch einen StringBuilder ersetzt werden
User8461

10
String hashWith256(String textToHash) {
    MessageDigest digest = MessageDigest.getInstance("SHA-256");
    byte[] byteOfTextToHash = textToHash.getBytes(StandardCharsets.UTF_8);
    byte[] hashedByetArray = digest.digest(byteOfTextToHash);
    String encoded = Base64.getEncoder().encodeToString(hashedByetArray);
    return encoded;
}

7

Ich habe den Apache-Code durchverfolgt DigestUtilsund sha256scheint java.security.MessageDigestfür die Berechnung standardmäßig auf zurück zu gehen . Apache implementiert keine unabhängige sha256Lösung. Ich suchte nach einer unabhängigen Implementierung, um sie mit der java.securityBibliothek zu vergleichen . Nur zu Ihrer Information.


3

Dies war mein Ansatz mit Kotlin:

private fun getHashFromEmailString(email : String) : String{
    val charset = Charsets.UTF_8
    val byteArray = email.toByteArray(charset)
    val digest = MessageDigest.getInstance("SHA-256")
    val hash = digest.digest(byteArray)

    return hash.fold("", { str, it -> str + "%02x".format(it)})
}

Hallo, ich habe gerade Ihren Code ausprobiert, weil ich in Android Studio ein Passwort hashen muss und Ihr Code ungefähr so ​​zurückgibt: [B@188363enicht das verschlüsselte Passwort. Außerdem scheint es jedes Mal anders zu sein, wenn diese Funktion aufgerufen wird.
Adrian2895

1
Behoben, du hast vergessen, return hash.fold("", { str, it -> str + "%02x".format(it)})welches das verschlüsselte Passwort und nicht das Objekt selbst zurückgibt.
Adrian2895

1
Ja, Sie haben Recht, lassen Sie mich die Antwort mit Ihrem Fix aktualisieren. Vielen Dank :)
Samuel Luís

2

Hier ist eine etwas performantere Möglichkeit, den Digest in eine Hex-Zeichenfolge umzuwandeln:

private static final char[] hexArray = "0123456789abcdef".toCharArray();

public static String getSHA256(String data) {
    StringBuilder sb = new StringBuilder();
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(data.getBytes());
        byte[] byteData = md.digest();
        sb.append(bytesToHex(byteData);
    } catch(Exception e) {
        e.printStackTrace();
    }
    return sb.toString();
}

private static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for ( int j = 0; j < bytes.length; j++ ) {
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return String.valueOf(hexChars);
}

Kennt jemand einen schnelleren Weg in Java?


1

Sie können MessageDigest folgendermaßen verwenden:

public static String getSHA256(String data){
    StringBuffer sb = new StringBuffer();
    try{
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(data.getBytes());
        byte byteData[] = md.digest();

        for (int i = 0; i < byteData.length; i++) {
         sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
        }
    } catch(Exception e){
        e.printStackTrace();
    }
    return sb.toString();
}

1

In Java 8

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;
import javax.xml.bind.DatatypeConverter;


Scanner scanner = new Scanner(System.in);
String password = scanner.nextLine();
scanner.close();

MessageDigest digest = null;
try {
    digest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
byte[] hash = digest.digest(password.getBytes(StandardCharsets.UTF_8));
String encoded = DatatypeConverter.printHexBinary(hash);        
System.out.println(encoded.toLowerCase());

0

In Java wird die MessageDigest- Klasse verwendet, um den kryptografischen Hashing-Wert zu berechnen. Diese Klasse bietet eine kryptografische Hash-Funktion ( MD5 , SHA-1 und SHA-256 ), um den Hash-Wert von Text zu ermitteln.

Codebeispiel für die Verwendung des SHA-256-Algorithmus.

public void printHash(String str) throws NoSuchAlgorithmException {

MessageDigest md=MessageDigest.getInstance("SHA-256");

byte[] sha256=md.digest(str.getBytes(StandardCharsets.UTF_8));

   for(byte b : sha256){

      System.out.printf("%02x",b);

  }
}

0

Dies ist, was ich für das Hashing verwendet wurde:

String pass = "password";

MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
byte hashBytes[] = messageDigest.digest(pass.getBytes(StandardCharsets.UTF_8));
BigInteger noHash = new BigInteger(1, hashBytes);
String hashStr = noHash.toString(16);

Ausgabe: 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8


-2
private static String getMessageDigest(String message, String algorithm) {
 MessageDigest digest;
 try {
  digest = MessageDigest.getInstance(algorithm);
  byte data[] = digest.digest(message.getBytes("UTF-8"));
  return convertByteArrayToHexString(data);
 } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 return null;
}

Sie können die obige Methode mit verschiedenen Algorithmen wie unten aufrufen.

getMessageDigest(message, "MD5");
getMessageDigest(message, "SHA-256");
getMessageDigest(message, "SHA-1");

Sie können diesen Link für die vollständige Anwendung verweisen .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.