39 votes

Comment générer un HMAC en Java équivalent à un exemple Python?

Je suis à la recherche à la mise en œuvre d'une application se Twitter autorisation via Oauth en Java. La première étape est l'obtention d'un jeton de demande. Voici un exemple Python pour app engine. Pour tester mon code, je suis en cours d'exécution Python et la vérification de sortie avec Java. Voici un exemple de Python générer un Hash Message Authentication Code (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]

Sortie:

$ ./foo.py
+3h2gpjf4xcynjCGU5lbdMBwGOc=

Comment reproduire cet exemple en Java?

J'ai vu un exemple 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) {
}

Il utilise javax.crypto.Mac, toutes les bonnes. Cependant, la SecretKey les constructeurs ont octets et d'un algorithme. Quel est l'algorithme dans l'exemple Python? Comment peut-on créer un Java clé secrète sans un algorithme?

57voto

Bruno Points 47560

HmacSHA1 semble être le nom de l'algorithme dont vous avez besoin:

 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));
 

produit:

 +3h2gpjf4xcynjCGU5lbdMBwGOc=
 

Notez que j'ai utilisé sun.misc.BASE64Encoder pour une implémentation rapide ici, mais vous devriez probablement utiliser quelque chose qui ne dépend pas du JRE de Sun. Le codeur base64 dans le codec Commons serait un meilleur choix, par exemple.

15voto

markltbaker Points 153

Une chose mineure, mais si vous êtes à la recherche d'un équivalent à l'algorithme hmac(clé,message), alors par défaut, la bibliothèque python va utiliser l'algorithme MD5, si vous avez besoin d'utiliser le HmacMD5 algorithme en Java.

Je mentionne cela parce que j'ai eu exactement ce problème et trouvé cette réponse qui m'a été utile, mais j'ai raté la partie où un condensé de la méthode a été adoptée à hmac() et descendit donc un trou de lapin. J'espère que cette réponse va empêcher les autres à faire de même dans l'avenir.

par exemple en Python REPL

>>> import hmac
>>> hmac.new("keyValueGoesHere", "secretMessageToHash").hexdigest()
'1a7bb3687962c9e26b2d4c2b833b2bf2'

Ceci est équivalent à la méthode 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);
    }
}

Notez que dans mon exemple, je suis en train de faire l'équivalent d' .hexdigest()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: