Hashing SHA-256 y SHA3-256 en Java

Parte superior de Java

Acabo de anunciar el nuevo curso Learn Spring , centrado en los fundamentos de Spring 5 y Spring Boot 2:

>> VER EL CURSO

1. Información general

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

El algoritmo SHA-256 genera un hash casi único de tamaño fijo de 256 bits (32 bytes). Esta es una función unidireccional, por lo que el resultado no se puede descifrar al valor original.

Actualmente, el hash SHA-2 se utiliza ampliamente, 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 unidireccional único, 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.

NIST lanzó 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 estuvieron disponibles en los proveedores predeterminados integrados.

Ahora, comencemos con SHA-256.

2. Clase 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 usar un convertidor de byte a hexadecimal personalizado para obtener el valor 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[i]); if(hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString(); }

Debemos ser conscientes de que MessageDigest no es seguro para subprocesos . En consecuencia, deberíamos usar una nueva instancia para cada hilo.

3. Biblioteca de guayaba

La biblioteca de Google Guava también proporciona una clase de utilidad para el hash.

Primero, definamos la dependencia:

 com.google.guava guava 20.0 

Ahora, así es como podemos usar Guava para hash una cadena:

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

4. Códecs Apache Commons

Del mismo modo, también podemos usar Apache Commons Codecs:

 commons-codec commons-codec 1.11 

Aquí está la clase de utilidad, llamada DigestUtils , que admite el hash SHA-256:

String sha256hex = DigestUtils.sha256Hex(originalString);

5. Biblioteca del castillo hinchable

5.1. Dependencia de Maven

 org.bouncycastle bcprov-jdk15on 1.60 

5.2. Hashing usando la biblioteca del castillo hinchable

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

Sin embargo, primero es necesario completar un resumen utilizando la API de Java incorporada:

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

6. SHA3-256

Ahora continuemos con SHA3-256. El hash SHA3-256 en Java no es muy diferente de SHA-256.

6.1. Clase MessageDigest en Java

A partir de JDK 9, simplemente podemos usar 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. Códecs de Apache Commons

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

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

6.3. Keccak-256

Keccak-256 es otro algoritmo de hash SHA3-256 popular. Actualmente, sirve como alternativa al estándar SHA3-256. Keccak-256 ofrece el mismo nivel de seguridad que el estándar SHA3-256 y se diferencia del SHA3-256 solo en la regla de relleno. Se ha utilizado en varios proyectos de blockchain, como Monoro.

Nuevamente, necesitamos importar la biblioteca de Bouncy Castle para usar el hash 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 hash:

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

7. Conclusión

En este artículo rápido, echamos un vistazo a algunas formas de implementar el hash SHA-256 y SHA3-256 en Java, utilizando bibliotecas integradas y de terceros.

El código fuente de los ejemplos anteriores se puede encontrar en el proyecto GitHub.

Fondo de Java

Acabo de anunciar el nuevo curso Learn Spring , centrado en los fundamentos de Spring 5 y Spring Boot 2:

>> VER EL CURSO