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

je suis à la recherche de la mise en œuvre d'une application Obtenir autorisation Twitter via Oauth en Java. La première étape est obtenir une demande de jeton. Voici un exemple Python pour app engine.

pour tester mon code, J'exécute Python et je vérifie la sortie avec Java. Voici un exemple de code d'authentification de Message (HMAC) généré par Python:

#!/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 répliquer ceci 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) {
}

javax.cryptographique.Mac, tous les bons. Cependant, le SecretKey les constructeurs prennent des octets et un algorithme.

Quel est l'algorithme dans l'exemple Python? Comment créer une clé secrète Java sans algorithme?

46
demandé sur Kevin Guan 2010-07-09 01:31:20

2 réponses

HmacSHA1 semble être le nom de l'algorithme que 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 Sun JRE. Le base64-encoder à la chambre des Communes Codec serait un meilleur choix, par exemple.

65
répondu Bruno 2012-02-22 12:44:05

une chose mineure mais si vous cherchez un équivalent à hmac (clé,message) alors par défaut la bibliothèque python utilisera L'algorithme MD5, donc vous devez utiliser L'algorithme HmacMD5 en Java.

j'ai mentionné ceci parce que j'avais ce problème précis et j'ai trouvé cette réponse qui était utile, mais j'ai manqué la partie où une méthode de digest a été transmise à hmac() et ainsi suis descendu dans un terrier de lapin. J'espère que cette réponse empêchera d'autres personnes de faire de même dans la avenir.

par exemple en Python REPL

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

c'est l'équivalent de la méthode 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 fais l'équivalent de .hexdigest ()

20
répondu markltbaker 2012-06-19 13:43:34