java - online hash_hmac
¿Cómo generar un HMAC en Java equivalente a un ejemplo de Python? (2)
HmacSHA1 parece ser el nombre del algoritmo que necesita:
SecretKeySpec keySpec = new SecretKeySpec(
"qnscAdgRlkIhAUPY44oiexBKtQbGY0orf7OV1I50".getBytes(),
"HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(keySpec);
byte[] result = mac.doFinal("foo".getBytes());
BASE64Encoder encoder = new BASE64Encoder();
System.out.println(encoder.encode(result));
produce:
+3h2gpjf4xcynjCGU5lbdMBwGOc=
Tenga en cuenta que he usado sun.misc.BASE64Encoder
para una implementación rápida aquí, pero probablemente debería usar algo que no dependa del Sun JRE. El codificador base64 en Commons Codec sería una mejor opción, por ejemplo.
Estoy considerando la implementación de una aplicación para obtener la autorización de Twitter a través de Oauth en Java. El primer paso es obtener un token de solicitud . Aquí hay un ejemplo de Python para el motor de aplicaciones.
Para probar mi código, estoy ejecutando Python y comprobando la salida con Java. Aquí hay un ejemplo de Python que genera un código de autenticación de mensaje basado en hash (HMAC):
#!/usr/bin/python
from hashlib import sha1
from hmac import new as hmac
key = "qnscAdgRlkIhAUPY44oiexBKtQbGY0orf7OV1I50"
message = "foo"
print "%s" % hmac(key, message, sha1).digest().encode(''base64'')[:-1]
Salida:
$ ./foo.py
+3h2gpjf4xcynjCGU5lbdMBwGOc=
¿Cómo se replica este ejemplo en Java?
He visto un ejemplo de HMAC en Java:
try {
// Generate a key for the HMAC-MD5 keyed-hashing algorithm; see RFC 2104
// In practice, you would save this key.
KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
SecretKey key = keyGen.generateKey();
// Create a MAC object using HMAC-MD5 and initialize with key
Mac mac = Mac.getInstance(key.getAlgorithm());
mac.init(key);
String str = "This message will be digested";
// Encode the string into bytes using utf-8 and digest it
byte[] utf8 = str.getBytes("UTF8");
byte[] digest = mac.doFinal(utf8);
// If desired, convert the digest into a string
String digestB64 = new sun.misc.BASE64Encoder().encode(digest);
} catch (InvalidKeyException e) {
} catch (NoSuchAlgorithmException e) {
} catch (UnsupportedEncodingException e) {
}
Utiliza javax.crypto.Mac , todo bien. Sin embargo, los constructores SecretKey toman bytes y un algoritmo.
¿Cuál es el algoritmo en el ejemplo de Python? ¿Cómo se puede crear una clave secreta de Java sin un algoritmo?
Una cosa menor, pero si está buscando un equivalente a hmac (clave, mensaje), entonces, de forma predeterminada, la biblioteca de Python usará el algoritmo MD5, por lo que necesita usar el algoritmo HmacMD5 en Java.
Mencioné esto porque tuve este problema exacto y encontré esta respuesta que fue útil, pero me perdí la parte en que se pasó un método de resumen a hmac () y, por lo tanto, bajé por un agujero de conejo. Esperemos que esta respuesta evite que otros hagan lo mismo en el futuro.
por ejemplo en Python REPL
>>> import hmac
>>> hmac.new("keyValueGoesHere", "secretMessageToHash").hexdigest()
''1a7bb3687962c9e26b2d4c2b833b2bf2''
Esto es equivalente al método de Java:
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class HashingUtility {
public static String HMAC_MD5_encode(String key, String message) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(
key.getBytes(),
"HmacMD5");
Mac mac = Mac.getInstance("HmacMD5");
mac.init(keySpec);
byte[] rawHmac = mac.doFinal(message.getBytes());
return Hex.encodeHexString(rawHmac);
}
}
Tenga en cuenta que en mi ejemplo estoy haciendo el equivalente de .hexdigest ()