web-dev-qa-db-fra.com

HMAC-SHA1: Comment le faire correctement en Java?

Je hache certaines valeurs en utilisant HMAC-SHA1, en utilisant le code suivant en Java:

public static String hmacSha1(String value, String key) {
    try {
        // Get an hmac_sha1 key from the raw key bytes
        byte[] keyBytes = key.getBytes();           
        SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1");

        // Get an hmac_sha1 Mac instance and initialize with the signing key
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(signingKey);

        // Compute the hmac on input data bytes
        byte[] rawHmac = mac.doFinal(value.getBytes());

        // Convert raw bytes to Hex
        byte[] hexBytes = new Hex().encode(rawHmac);

        //  Covert array of Hex bytes to a String
        return new String(hexBytes, "UTF-8");
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

Hex() appartient à org.Apache.commons.codec

Dans PHP, il existe une fonction similaire hash_hmac(algorithm, data, key) que j'utilise pour comparer les valeurs renvoyées par mon implémentation Java.

Donc, le premier essai est:

hash_hmac("sha1", "helloworld", "mykey") // PHP

qui retourne: 74ae5a4a3d9996d5918defc2c3d475471bbf59ac

Ma fonction Java renvoie également 74ae5a4a3d9996d5918defc2c3d475471bbf59ac.

Ok, ça a l'air de marcher. Ensuite, j'essaie d'utiliser une clé plus complexe:

hash_hmac("sha1", "helloworld", "PRIE7$oG2uS-Yf17kEnUEpi5hvW/#AFo") // PHP

qui retourne: e98bcc5c5be6f11dc582ae55f520d1ec4ae29f7a

Alors que cette fois, mon Java impl renvoie: c19fccf57c613f1868dd22d586f9571cf6412cd0

Le hachage renvoyé par mon code PHP n'est pas égal à la valeur renvoyée par ma fonction Java et je ne parviens pas à savoir pourquoi.

Des conseils?

50
Mark

De votre côté PHP, utilisez des guillemets simples autour de la clé pour que le caractère $ ne soit pas traité comme une référence de variable. c'est à dire.,

hash_hmac("sha1", "helloworld", 'PRIE7$oG2uS-Yf17kEnUEpi5hvW/#AFo')

Sinon, la clé que vous obtenez réellement est PRIE7-Yf17kEnUEpi5hvW/#AFo (en supposant que la variable $oG2uS n'est pas définie).

50
Chris Jester-Young

Recommend Apache Common Codec Library , assez simple et facile à utiliser .HmacUtils.hmacSha1Hex(key, string_to_sign);

15
Armstrongya

Tout symbole $ entre guillemets ("") est considéré comme une variable en PHP. Vous pouvez éviter l'erreur en utilisant des guillemets simples comme indiqué par le commentaire précédent ou en évitant le signe dollar comme ci-dessous

hash_hmac("sha1", "helloworld", "PRIE7\$oG2uS-Yf17kEnUEpi5hvW/#AFo")

Avis que $ est maintenant\$

7
tlogbon

Dans Java , et en utilisant maven :

Ajoutez la dépendance ci-dessous dans le pom.xml:

 <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.4</version>
    </dependency>

puis essayez de le signer en utilisant cette

HmacUtils.hmacSha1Hex(key, string_to_sign);
1
Salman Lashkarara