SHA-256 y SHA3-256 Hashing en Java

Resumen

El SHA (Secure Hash Algorithm) es una de las funciones hash criptográficas más populares. Un hash criptográfico puede ser usado para hacer una firma para un texto o un archivo de datos. En este tutorial, vamos a echar un vistazo a cómo podemos realizar operaciones de hash SHA-256 y SHA3-256 utilizando varias bibliotecas de Java.

El algoritmo SHA-256 genera un hash casi único de tamaño fijo de 256 bits (32 bytes). Se trata de una función unidireccional, por lo que el resultado no puede ser descifrado hasta llegar al valor original.

Actualmente, el hash SHA-2 es muy utilizado ya que se considera el algoritmo de hash más seguro en el ámbito criptográfico.

SHA-3 es el último estándar de hash seguro después de SHA-2. En comparación con SHA-2, SHA-3 proporciona un enfoque diferente para generar un hash único de una vía, y puede ser mucho más rápido en algunas implementaciones de hardware. Similar a SHA-256, SHA3-256 es el algoritmo de longitud fija de 256 bits en SHA-3.

El NIST publicó SHA-3 en 2015, por lo que no hay tantas bibliotecas SHA-3 como SHA-2 por el momento. No es hasta JDK 9 que los algoritmos SHA-3 estaban disponibles en los proveedores incorporados por defecto.

Ahora, vamos a empezar con SHA-256.

Más lecturas:

Locality-Sensitive Hashing in Java Using Java-LSH

Una guía rápida y práctica para aplicar el algoritmo Locality-Sensitive Hashing en Java utilizando la librería java-lsh.
Leer más →

MD5 Hashing en Java

Un escrito rápido que muestra cómo tratar el hashing MD5 en Java.
Leer más →

Una guía de HashSet en Java

Una rápida pero completa introducción a HashSet en Java.
Leer más →

Clases MessageDigest en Java

Java proporciona la clase MessageDigest incorporada para el hash SHA-256:

MessageDigest digest = MessageDigest.getInstance("SHA-256");byte encodedhash = digest.digest( originalString.getBytes(StandardCharsets.UTF_8));

Sin embargo, aquí tenemos que utilizar un convertidor personalizado de bytes a hexadecimal para obtener el valor del hash en hexadecimal:

private static String bytesToHex(byte hash) { StringBuilder hexString = new StringBuilder(2 * hash.length); for (int i = 0; i < hash.length; i++) { String hex = Integer.toHexString(0xff & hash); if(hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString();}

Tenemos que ser conscientes de que el MessageDigest no es seguro para los hilos. En consecuencia, debemos utilizar una nueva instancia para cada hilo.

Librería Guava

La librería Guava de Google también proporciona una clase de utilidad para el hash.

Primero, vamos a definir la dependencia:

<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>20.0</version></dependency>

Ahora, así es como podemos usar Guava para hacer hash de un String:

String sha256hex = Hashing.sha256() .hashString(originalString, StandardCharsets.UTF_8) .toString();

Apache Commons Codecs

De forma similar, también podemos utilizar Apache Commons Codecs:

<dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.11</version></dependency>

Aquí tienes la clase de utilidad -llamada DigestUtils- que soporta el hashing SHA-256:

String sha256hex = DigestUtils.sha256Hex(originalString);

Biblioteca del castillo hinchable

5.1. Dependencia de Maven

<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.60</version></dependency>

5.2. Hashing usando la librería Bouncy Castle

La API Bouncy Castle proporciona una clase de utilidad para convertir datos hexadecimales a bytes y viceversa.

Sin embargo, se requiere poblar un digest usando la API Java incorporada primero:

MessageDigest digest = MessageDigest.getInstance("SHA-256");byte hash = digest.digest( originalString.getBytes(StandardCharsets.UTF_8));String sha256hex = new String(Hex.encode(hash));

SHA3-256

Ahora vamos a continuar con SHA3-256. El hashing SHA3-256 en Java no es nada diferente de SHA-256.

6.1. Clase MessageDigest en Java

A partir de JDK 9, podemos utilizar simplemente el algoritmo SHA3-256 incorporado:

final MessageDigest digest = MessageDigest.getInstance("SHA3-256");final byte hashbytes = digest.digest( originalString.getBytes(StandardCharsets.UTF_8));String sha3Hex = bytesToHex(hashbytes);

6.2. Apache Commons Codecs

Apache Commons Codecs proporciona un práctico envoltorio DigestUtils para la clase MessageDigest. Esta biblioteca comenzó a soportar SHA3-256 desde la versión 1.11, y requiere también JDK 9+:

String sha3Hex = new DigestUtils("SHA3-256").digestAsHex(originalString);

6.3. Keccak-256

Keccak-256 es otro popular algoritmo de hash SHA3-256. Actualmente, sirve como alternativa al estándar SHA3-256. Keccak-256 ofrece el mismo nivel de seguridad que el SHA3-256 estándar, y difiere de SHA3-256 sólo en la regla de relleno. Se ha utilizado en varios proyectos de blockchain, como Monero.

De nuevo, necesitamos importar la librería Bouncy Castle para usar el hashing Keccak-256:

Security.addProvider(new BouncyCastleProvider());final MessageDigest digest = MessageDigest.getInstance("Keccak-256");final byte encodedhash = digest.digest( originalString.getBytes(StandardCharsets.UTF_8));String sha3Hex = bytesToHex(encodedhash);

También podemos hacer uso de la API de Bouncy Castle para hacer el hashing:

Keccak.Digest256 digest256 = new Keccak.Digest256();byte hashbytes = digest256.digest( originalString.getBytes(StandardCharsets.UTF_8));String sha3Hex = new String(Hex.encode(hashbytes));

Conclusión

En este rápido artículo, hemos echado un vistazo a unas cuantas formas de implementar el hashing SHA-256 y SHA3-256 en Java, utilizando tanto librerías incorporadas como de terceros.

Deja una respuesta

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