Tengo una función hash simple en Java que reescribí en Node.js pero producen resultados diferentes.
Aquí está el Java:
public static String get_SHA_512_SecurePassword(String str, String customerId) { try { MessageDigest instance = MessageDigest.getInstance("SHA-512"); instance.update(customerId.getBytes(StandardCharsets.UTF_8)); byte[] digest = instance.digest(str.getBytes(StandardCharsets.UTF_8)); StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(Integer.toString((b & 255) + 256, 16).substring(1)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } }y aquí está el equivalente de Node.js que produje.
let crypto = require('crypto'); function get_SHA_512_SecurePassword(str, customerId) { let hash = crypto.createHash('sha512') hash.update(customerId, 'utf8') let value = hash.digest(str, 'uft8') console.log(value.toString('hex')) return value.toString('hex'); }¿Alguien puede explicar qué estoy haciendo mal o por qué son diferentes si reproduzco bien?
Ya casi llega, el problema es que la función .digest no acepta un argumento en Node.js, por lo que llamaremos a .update dos veces, una con customerId y luego con str. En realidad, no necesitamos pasar la codificación de cadena a la función .update ya que utf8 es la codificación predeterminada.
const crypto = require('crypto'); function get_SHA_512_SecurePassword(str, customerId) { const hash = crypto.createHash('sha512'); const digest = hash.update(customerId, "utf-8").update(str, "utf-8").digest(); return digest.toString("hex"); } console.log(get_SHA_512_SecurePassword("hello", "world"));Este ejemplo de Node.js produce:
3e64afa1cb7d643aa36f63b8d092ad76b1f04ff557abbb3d05f5b9037abf68a6606a8885d51bec8f6f39ee7d0badd504241c3704e777a51c21a9723e285fb9b8
Que debería ser el mismo resultado que el código Java.
Su problema es que usa mal la criptografía en node.js. El método digest () en java es un poco diferente que en crypto en node.js
Documentación de la API de MessageDigest de Java
digest(byte[] input) Realiza una actualización final en el resumen usando la matriz de bytes especificada, luego completa el cálculo del resumen.
Entonces, en Java, proporciona otra cadena en resumen y la consume para producir un nuevo hash y luego produce la salida
En node.js, sin embargo, la documentación para hmac.digest() indica Crypto Doc
hmac.digest([encoding])Calcula el resumen HMAC de todos los datos pasados mediante hmac.update(). Si se proporciona codificación, se devuelve una cadena; de lo contrario, se devuelve un búfer;
Por lo tanto, no aceptará que se codifique otra cadena como si pasara str en esa función. Solo aceptará una codificación.
Entonces en tu código
function get_SHA_512_SecurePassword(str, customerId) { let hash = crypto.createHash('sha512') hash.update(customerId, 'utf8') let value = hash.digest(str, 'uft8') <-----this is wrong console.log(value.toString('hex')) return value.toString('hex'); }La siguiente seria la correcta
function get_SHA_512_SecurePassword(str, customerId) { let hash = crypto.createHash('sha512') hash.update(customerId, 'utf8') hash.update(str, 'utf8') let value = hash.digest('hex') console.log(value) return value; }