¿Cómo hacer hash de String con SHA-256 en Java?

5 minutos de lectura

Avatar de usuario de Ivana
ivana

¿Cómo puedo hacer hash algunos String con SHA-256 en Java?

  • posible duplicado de Hash String a través de SHA-256 en Java

    – mmmmmm

    11 de agosto de 2014 a las 12:25

  • baeldung.com/sha-256-hashing-java

    – Barett

    31 de marzo de 2020 a las 21:47

Avatar de usuario de Jon Skeet
jon skeet

SHA-256 no es una “codificación”, es un hash unidireccional.

Básicamente, convertiría la cadena en bytes (por ejemplo, usando text.getBytes(StandardCharsets.UTF_8)) y luego hash los bytes. Tenga en cuenta que el resultado del hash sería además ser datos binarios arbitrarios, y si desea representar eso en una cadena, debe usar base64 o hexadecimal … no intenta usar el String(byte[], String) constructor.

p.ej

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

  • “SHA-256 no es una codificación” absolutamente correcto, pero debo decir que prefiero el título de la pregunta actual a “cómo encriptar con sha” (muchos parecen pensar que es encriptación). Tal vez deberíamos tratarlo como una codificación en lugar de algo relacionado con la criptografía porque en la práctica es más parecido a cómo se usa.

    – Lucas

    10 de junio de 2014 a las 12:32


  • @Luc: Bueno, es un hash criptográfico, así que no creo que sea irrazonable decirlo. lo hace tienen algo que ver con la criptografía… el cifrado y la criptografía no son intercambiables…

    – Jon Skeet

    10 de junio de 2014 a las 12:34

  • Nota: es una buena idea usar Conjuntos de caracteres estándar.UTF_8 en vez de "UTF-8" literal en Java 7+: una excepción comprobada menos de qué preocuparse.

    – kryger

    1 de diciembre de 2015 a las 21:59


  • ¿Por qué debería evitar el String(byte[]String) cuando se trata del resultado hash?

    –Isaac van Bakel

    18 de abril de 2016 a las 13:03

  • @IsaacvanBakel: Porque un hash no es texto codificado. Son datos binarios arbitrarios.

    – Jon Skeet

    18 de abril de 2016 a las 13:04

Creo que la solución más fácil es usar Códec común de Apache:

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

  • La mejor respuesta, fácil de usar, limpio. ¡Gracias!

    – fl0w

    16 de enero de 2020 a las 15:55

Avatar de usuario de Jonathan
jonathan

Otra alternativa es Guayaba que tiene un conjunto fácil de usar de hash utilidades. Por ejemplo, para codificar una cadena usando SHA256 como una cadena hexadecimal, simplemente haría lo siguiente:

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

  • Solo para tener en cuenta: desde la introducción en la versión 11, todavía se marcaba como @Beta en la versión 30.

    – suave

    6 de agosto de 2021 a las 11:23

avatar de usuario de user1452273
usuario1452273

Hash de ejemplo completo a cadena como otra cadena.

public static String sha256(final String base) {
    try{
        final MessageDigest digest = MessageDigest.getInstance("SHA-256");
        final byte[] hash = digest.digest(base.getBytes("UTF-8"));
        final StringBuilder hexString = new StringBuilder();
        for (int i = 0; i < hash.length; i++) {
            final 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);
    }
}

Avatar de usuario de Eduardo Dennis
eduardo dennis

Si está utilizando Java 8, puede codificar el byte[] haciendo

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

  • De esta manera es conveniente para mí. Sin embargo, debe usar el siguiente Base64.encodeToString(hash, Base64.DEFAULT);

    –Motassem Jalal

    27 de junio de 2017 a las 10:53

  • @MotassemJalal Base64.DEFAULT no está disponible en la última versión de Java8, actualmente estoy usando jdk1.8.0_144. ¿Puede decirme cómo lo creó?

    – rajadilipkolli

    1 de diciembre de 2017 a las 7:30

  • @rajadilipkolli Creo que es la implementación de Android: desarrollador.android.com/reference/android/util/Base64

    – dbm

    11 de junio de 2018 a las 19:33

  • Por alguna razón, obtengo un resultado incorrecto de esto. Ejemplo: para la entrada de “prueba”, obtuve n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg= en vez de 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 . ¿Cómo?

    – desarrollador de Android

    14 de marzo de 2021 a las 13:39

  • Es una forma de hacerlo, pero no el estándar común. @Android Developer, es por eso que está viendo un valor diferente aquí que lo que vería en otras implementaciones.

    – Durga Swaroop

    30 de agosto de 2021 a las 11:10


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();
 }
}

  • De esta manera es conveniente para mí. Sin embargo, debe usar el siguiente Base64.encodeToString(hash, Base64.DEFAULT);

    –Motassem Jalal

    27 de junio de 2017 a las 10:53

  • @MotassemJalal Base64.DEFAULT no está disponible en la última versión de Java8, actualmente estoy usando jdk1.8.0_144. ¿Puede decirme cómo lo creó?

    – rajadilipkolli

    1 de diciembre de 2017 a las 7:30

  • @rajadilipkolli Creo que es la implementación de Android: desarrollador.android.com/reference/android/util/Base64

    – dbm

    11 de junio de 2018 a las 19:33

  • Por alguna razón, obtengo un resultado incorrecto de esto. Ejemplo: para la entrada de “prueba”, obtuve n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg= en vez de 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 . ¿Cómo?

    – desarrollador de Android

    14 de marzo de 2021 a las 13:39

  • Es una forma de hacerlo, pero no el estándar común. @Android Developer, es por eso que está viendo un valor diferente aquí que lo que vería en otras implementaciones.

    – Durga Swaroop

    30 de agosto de 2021 a las 11:10


Avatar de usuario de Bagrat Kirakosian
Bagrat Kirakosian

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;
}

¿Ha sido útil esta solución?