Hashing SHA-256 e SHA3-256 em Java
1. Visão geral
O SHA (Secure Hash Algorithm) é uma das funções populares de hash criptográfico. Um hash criptográfico pode ser usado para criar uma assinatura para um arquivo de texto ou dados. Neste tutorial, vamos dar uma olhada em como podemos realizar operações de hash SHA-256 e SHA3-256 usando várias bibliotecas Java.
O algoritmoSHA-256 gera um hash quase exclusivo de 256 bits (32 bytes) de tamanho fixo. Esta é uma função unidirecional, portanto, o resultado não pode ser descriptografado de volta ao valor original.
Atualmente, o hash SHA-2 é amplamente utilizado, pois é considerado o algoritmo de hash mais seguro na arena criptográfica.
SHA-3 é o padrão de hash seguro mais recente após SHA-2. Comparado ao SHA-2, o SHA-3 fornece uma abordagem diferente para gerar um hash unidirecional exclusivo e pode ser muito mais rápido em algumas implementações de hardware. Semelhante ao SHA-256, o SHA3-256 é o algoritmo de comprimento fixo de 256 bits no SHA-3.
NIST lançou o SHA-3 em 2015, portanto, não há tantas bibliotecas SHA-3 quanto o SHA-2 por enquanto. Somente no JDK 9 é que os algoritmos SHA-3 estavam disponíveis nos provedores padrão integrados.
Agora, vamos começar com SHA-256.
Leitura adicional:
Hashing sensível à localidade em Java usando Java-LSH
Um guia rápido e prático para aplicar o algoritmo de Hashing sensível à localidade em Java usando a biblioteca java-lsh.
Um guia para o HashSet em Java
Uma introdução rápida, mas abrangente, ao HashSet em Java.
2. ClasseMessageDigest em Java
Java fornece a classeMessageDigest embutida para hashing SHA-256:
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] encodedhash = digest.digest(
originalString.getBytes(StandardCharsets.UTF_8));
No entanto, aqui temos que usar um byte personalizado para o conversor hexadecimal para obter o valor do hash em hexadecimal:
private static String bytesToHex(byte[] hash) {
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();
}
3. Biblioteca Guava
A biblioteca do Google Guava também fornece uma classe de utilitário para hash.
Primeiro, vamos definir a dependência:
com.google.guava
guava
20.0
Agora, aqui está como podemos usar Guava para hash uma String:
String sha256hex = Hashing.sha256()
.hashString(originalString, StandardCharsets.UTF_8)
.toString();
4. Codecs Apache Commons
Da mesma forma, também podemos usar os codecs do Apache Commons:
commons-codec
commons-codec
1.11
Esta é a classe de utilitário - chamadaDigestUtils - que suporta hashing SHA-256:
String sha256hex = DigestUtils.sha256Hex(originalString);
5. Bouncy Castle Library
5.1. Dependência do Maven
org.bouncycastle
bcprov-jdk15on
1.60
5.2. Hashing usando a Biblioteca do Bouncy Castle
A API do Bouncy Castle fornece uma classe de utilitário para converter dados hexadecimais em bytes e vice-versa.
No entanto, é necessário preencher um resumo usando a API Java incorporada primeiro:
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
Agora vamos continuar com SHA3-256. O hash SHA3-256 em Java não é nada diferente do SHA-256.
6.1. ClasseMessageDigest em Java
Starting from JDK 9, podemos simplesmente usar o algoritmo SHA3-256 integrado:
final MessageDigest digest = MessageDigest.getInstance(SHA3_256);
final byte[] hashbytes = digest.digest(
originalString.getBytes(StandardCharsets.UTF_8));
String sha3_256hex = bytesToHex(hashbytes);
6.2. Codecs Apache Commons
Apache Commons Codecs fornece um conveniente wrapperDigestUtils para a classeMessageDigest. Esta biblioteca começou a suportar SHA3-256 desde a versão1.11 e tambémrequires JDK 9+:
String sha3_256hex = new DigestUtils(SHA3_256).digestAsHex(originalString);
6.3. Keccak-256
Keccak-256 é outro algoritmo de hash SHA3-256 popular. Atualmente, serve como uma alternativa ao padrão SHA3-256. O Keccak-256 oferece o mesmo nível de segurança que o SHA3-256 padrão e difere do SHA3-256 apenas na regra de preenchimento. Ele foi usado em vários projetos de blockchain, comoMonoro.
Novamente, precisamos importar a Bouncy Castle Library para usar o 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 sha3_256hex = bytesToHex(encodedhash);
Também podemos usar a API do Bouncy Castle para fazer o hash:
Keccak.Digest256 digest256 = new Keccak.Digest256();
byte[] hashbytes = digest256.digest(
originalString.getBytes(StandardCharsets.UTF_8));
String sha3_256hex = new String(Hex.encode(hashbytes));
7. Conclusão
Neste artigo rápido, vimos algumas maneiras de implementar o hash SHA-256 e SHA3-256 em Java, usando bibliotecas internas e de terceiros.
O código-fonte dos exemplos acima pode ser encontrado emGitHub project.