imagen de autor
Por mkyong | Última actualización: 16 de junio de 2020
Visto: 440,801 | +436 pv/w

En Java, podemos utilizar MessageDigest para obtener un SHA-256 o SHA3-256 algoritmo de hash para hashear una cadena.

 MessageDigest md = MessageDigest.getInstance("SHA3-256"); byte result = md.digest(input);

Este artículo muestra cómo utilizar los algoritmos Java SHA-256 y SHA3-256 para generar un valor hash a partir de una cadena dada y una suma de comprobación de un archivo.

Nota
El hashing es una función de compresión unidireccional para convertir entradas de diferentes longitudes en una salida de longitud fija (valor hash).

SHA-2 y SHA-3

1.1 El SHA-2 (Secure Hash Algorithm 2) está definido en FIPS PUB 180-4. El SHA-2 es un algoritmo de hashing ampliamente utilizado y diseñado por la Agencia Nacional de Seguridad (NSA).

Java soporta los siguientes SHA-2 algoritmos:

  • SHA-224
  • SHA-256
  • SHA-384
  • SHA-512
  • SHA-512/224
  • SHA-512/256
  • El SHA-256 produce una salida de 256bits de salida, 32 bytes, mientras que SHA-512 produce una salida de 512 bits, 64 bytes.

String : Hello WorldSHA-256a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146eSHA-5122c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d8585719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b

1.2 El SHA-3 (Secure Hash Algorithm 3) está definido en FIPS PUB 202. El SHA-3 es el último miembro de los Algoritmos Hash Seguros, publicado por el Instituto Nacional de Estándares y Tecnología (NIST).

Java soporta los siguientes SHA-3 algoritmos:

  • SHA3-224
  • SHA3-256
  • SHA3-384
  • SHA3-512
String : Hello WorldSHA3-256e167f68d6563d75bb25f3aa49c29ef612d41352dc00606de7cbd630bb2665f51SHA3-5122c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d8585719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b
Más lecturas

  • Lee esto ¿Cuál es la diferencia entre SHA-3 y SHA-256?
  • Lee esta Comparación de las funciones SHA

Java SHA3-256 Hashing

Este ejemplo de Java hace el hash de una cadena con el algoritmo SHA3-256.

ShaUtils.java
package com.mkyong.crypto.hash;import java.nio.charset.Charset;import java.nio.charset.StandardCharsets;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class ShaUtils { private static final Charset UTF_8 = StandardCharsets.UTF_8; private static final String OUTPUT_FORMAT = "%-20s:%s"; public static byte digest(byte input, String algorithm) { MessageDigest md; try { md = MessageDigest.getInstance(algorithm); } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException(e); } byte result = md.digest(input); return result; } public static String bytesToHex(byte bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02x", b)); } return sb.toString(); } public static void main(String args) { //String algorithm = "SHA-256"; // if you perfer SHA-2 String algorithm = "SHA3-256"; String pText = "Hello World"; System.out.println(String.format(OUTPUT_FORMAT, "Input (string)", pText)); System.out.println(String.format(OUTPUT_FORMAT, "Input (length)", pText.length())); byte shaInBytes = ShaUtils.digest(pText.getBytes(UTF_8), algorithm); System.out.println(String.format(OUTPUT_FORMAT, algorithm + " (hex) ", bytesToHex(shaInBytes))); // fixed length, 32 bytes, 256 bits. System.out.println(String.format(OUTPUT_FORMAT, algorithm + " (length)", shaInBytes.length)); }}

Salida

Input (string) :Hello WorldInput (length) :11SHA3-256 (hex) :e167f68d6563d75bb25f3aa49c29ef612d41352dc00606de7cbd630bb2665f51SHA3-256 (length) :32

Trata de hacer el hash de otra cadena, de diferente longitud, para SHA3-256, la salida fija a 256 bits, 32 bytes.

Salida

Input (string) :Hello SHA HashingInput (length) :17SHA3-256 (hex) :72fbf4f3a807d344a1ee492ff4183edf72e45fab8dfa6a6e5447226233633bf8SHA3-256 (length) :32

Suma de comprobación de archivos SHA3-256 de Java

Un archivo en la carpeta resources.

sha-file.txt
Hello World

Este ejemplo utiliza el algoritmo SHA3-256 para generar una suma de comprobación para el archivo anterior.

ShaUtils.java
package com.mkyong.crypto.hash;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.nio.charset.Charset;import java.nio.charset.StandardCharsets;import java.security.DigestInputStream;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class ShaUtils { private static byte checksum(String filePath, String algorithm) { MessageDigest md; try { md = MessageDigest.getInstance(algorithm); } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException(e); } try (InputStream is = new FileInputStream(filePath); DigestInputStream dis = new DigestInputStream(is, md)) { while (dis.read() != -1) ; //empty loop to clear the data md = dis.getMessageDigest(); } catch (IOException e) { throw new IllegalArgumentException(e); } return md.digest(); } public static String bytesToHex(byte bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02x", b)); } return sb.toString(); } public static void main(String args) { String algorithm = "SHA3-256"; // get file path from resources String filePath = ClassLoader.getSystemResource("sha-file.txt").getFile(); byte hashInBytes = checksum(filePath, algorithm); System.out.println(bytesToHex(hashInBytes)); }}

Salida

e167f68d6563d75bb25f3aa49c29ef612d41352dc00606de7cbd630bb2665f51

NoSuchAlgorithmException

Lee esto para todos los Algoritmos MessageDigest soportados por Java. Si proporcionamos un algoritmo no existente, por ejemplo, SHA4-256, Java lanza java.security.NoSuchAlgorithmException.

MessageDigest md = MessageDigest.getInstance("SHA4-256");
java.security.NoSuchAlgorithmException: SHA4-256 MessageDigest not availableat com.mkyong.crypto.hash.ShaUtils.digest(ShaUtils.java:22)at com.mkyong.crypto.hash.ShaUtils.main(ShaUtils.java:65)Caused by: java.security.NoSuchAlgorithmException: SHA4-256 MessageDigest not availableat java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:159)at java.base/java.security.Security.getImpl(Security.java:700)at java.base/java.security.MessageDigest.getInstance(MessageDigest.java:178)at com.mkyong.crypto.hash.ShaUtils.digest(ShaUtils.java:20)... 1 more

Apache Commons Codec

Este ejemplo utiliza el popular Apache Commons Codec para hacer hash de una cadena con los algoritmos SHA.

pom.xml
<dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.14</version></dependency>
import org.apache.commons.codec.digest.DigestUtils; // SHA-2 byte hash1 = DigestUtils.sha256(""); // returns byte arrays String hash2 = DigestUtils.sha256Hex(""); // returns encoded hex // SHA-3 byte hash3 = DigestUtils.sha3_256(""); // returns byte arrays String hash4 = DigestUtils.sha3_256Hex(""); // returns encoded hex

Añadir Sal al hashing SHA

La sal es un dato aleatorio, una técnica para evitar los ataques rainbow. En Java, podemos utilizar SecureRandom para generar una sal (bytes aleatorios).

 public static byte getRandomNonce(int numBytes) { byte nonce = new byte; new SecureRandom().nextBytes(nonce); return nonce; }

Este ejemplo genera una sal aleatoria de 16 bytes y utiliza ByteBuffer para anteponerla a una cadena. Al final, utilizamos el algoritmo SHA3-256 para generar un valor hash a partir del salt + string.

 // get a 16 bytes random salt. byte salt = CryptoUtils.getRandomNonce(16); byte pText = "Hello World".getBytes(StandardCharsets.UTF_8); // combine two byte arrays byte input = ByteBuffer.allocate(salt.length + pText.length) .put(salt) .put(pText) .array(); // no salt, SHA3-256 System.out.println(bytesToHex(ShaUtils.digest(pText, "SHA3-256"))); // 16 bytes salt, SHA3-256 System.out.println(bytesToHex(ShaUtils.digest(input, "SHA3-256")));

Salida

# no salte167f68d6563d75bb25f3aa49c29ef612d41352dc00606de7cbd630bb2665f51# 16 bytes salta6c589937ea475fc942d31d154d359ff569ff99fa32ee5d996ff64eca2e7551b

Nota
Para el hash de las contraseñas, podemos utilizar Bcrypt o Argon2.

Descarga el código fuente

$ git clone https://github.com/mkyong/core-java

$ cd java-crypto

  • Wikipedia – SHA-3
  • Wikipedia – Algoritmos Hash seguros
  • Algoritmos MessageDigest
  • Java – Cómo convertir matrices de bytes a Hex
  • Java MD5 Hashing. Ejemplo
  • Java – Cómo unir y dividir matrices de bytes
  • imagen de autor

    mkyong

    Fundador de Mkyong.com, amante de Java y de las cosas de código abierto. Síguelo en Twitter. Si te gustan mis tutoriales, considera hacer una donación a estas organizaciones benéficas.

Categorías: Articles

0 comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *