es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Java hmacSHA256 con BigInteger es diferente en comparación con C#

Ayer me encontré con un problema con el hashing utilizando Java y C#.

Tengo este código en C#:

byte[] message = Encoding.UTF8.GetBytes(“nick”);
byte[] key = Encoding.UTF8.GetBytes(“key”);

HMACSHA256 hmac = new HMACSHA256(key);
byte[] HmacBytes = hmac.ComputeHash(message);

var result = BitConverter.toString(HmacBytes);

_logger.LogInformation($”>>> HMAC: ” + result);

y este código en Java:

byte[] message = “nick”.getBytes(“UTF-8”);
byte[] key = “key”.getBytes(“UTF-8”);

Mac sha256HMAC = Mac.getInstance(“HmacSHA256”);
SecretKeySpec secretKey = new SecretKeySpec(key, sha256HMAC.getAlgorithm());
sha256HMAC.init(secretKey);

byte[] hmacBytes = sha256HMAC.doFinal(message);

System.out.println(“>>> HMAC: ” + Utils.bytesToHex(hmacBytes));

Ambos códigos tienen el mismo resultado como:
D56F32BEB288697DBC666CFCE330750240EE7252A8EACB90F30AE5EC2B6544FE

Sin embargo, si uso el mensaje y la clave con una variable BigInteger, el resultado eventualmente fue diferente.

Específicamente:

La variable BigInteger de clave:
89846755145779207896151571317970843398423995352339053147606272151939451164346932712779779593562801986871149751592444563734853909794103626366575265329402498505873220784518950449894168432504409626921891704398413417881679930643396500380895818666783852587744861261584959964779866038266086235614583684537765854767

La variable BigInteger de mensaje:
105278801605955351183032861925660079240049371193037037019863031780531990060755731057393990664319512505978954889835933668032824049054190807125138251307247771506918060803959346902566451812689470408398611041302277800747341495594297701677567604614145074223483256879948522462707345079591319551080307454838134385381

y cambio en C#:

HMACSHA256 hmac = new HMACSHA256(key.toByteArray());
byte[] HmacBytes = hmac.ComputeHash(message.toByteArray());

var result = BitConverter.toString(HmacBytes);

_logger.LogInformation($”>>> HMAC: ” + result);

igual en Java

Mac sha256HMAC = Mac.getInstance(“HmacSHA256”);
SecretKeySpec secretKey = new SecretKeySpec(key.toByteArray(), sha256HMAC.getAlgorithm());
sha256HMAC.init(secretKey);

byte[] hmacBytes = sha256HMAC.doFinal(message.toByteArray());

System.out.println(“>>> HMAC: ” + Utils.bytesToHex(hmacBytes));

Entonces, el resultado es muy diferente cuando en C#:
ED12EC5908E91F9F9CCE0AB8D703DC31A7DE70B20A39FC5C9A35C9193019C6D2

y en Java:
827EE601E601B44BF09D34947A7255EE484596B8C7DBEF283A64EE5C9BDA0CD1

¿Qué debo corregir en Java para que coincida con el resultado de C#?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema con el código Java es que asume que la clave y el mensaje son texto codificado en UTF-8, cuando en realidad son matrices de bytes. Para solucionar el código Java, debes eliminar las llamadas al método .getBytes("UTF-8") y pasar las variables BigInteger directamente al método de cálculo HMAC, como sigue:

    byte[] message = messageBigInteger.toByteArray();
    byte[] key = keyBigInteger.toByteArray();
    
    Mac sha256HMAC = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(key, sha256HMAC.getAlgorithm());
    sha256HMAC.init(secretKey);
    
    byte[] hmacBytes = sha256HMAC.doFinal(message);
    
    System.out.println(">>> HMAC: " + Utils.bytesToHex(hmacBytes));
    

    Esto debería producir el mismo resultado que el código C#.

Comments are closed.