87 votes

Algorithme HMAC-SHA256 pour le calcul de la signature

J'essaie de créer une signature à l'aide de l'algorithme HMAC-SHA256 et voici mon code. J'utilise l'encodage US ASCII.

 final Charset asciiCs = Charset.forName("US-ASCII");
final Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
final SecretKeySpec secret_key = new javax.crypto.spec.SecretKeySpec(asciiCs.encode("key").array(), "HmacSHA256");
sha256_HMAC.init(secret_key);
final byte[] mac_data = sha256_HMAC.doFinal(asciiCs.encode("The quick brown fox jumps over the lazy dog").array());
String result = "";
for (final byte element : mac_data)
{
    result += Integer.toString((element & 0xff) + 0x100, 16).substring(1);
}
System.out.println("Result:[" + result + "]");

Le résultat que j'obtiens du code ci-dessus est :

 f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

C'est le même que celui de montré dans le wiki

 HMAC_SHA256("key", "The quick brown fox jumps over the lazy dog") = 0x f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

sauf pour le 0x .

Je suis à la recherche d'idées/commentaires si je fais tout correctement ou si je peux améliorer mon code.

96voto

vtlinh Points 187

Voici ma solution :

 public static String encode(String key, String data) throws Exception {
  Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
  SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
  sha256_HMAC.init(secret_key);

  return Hex.encodeHexString(sha256_HMAC.doFinal(data.getBytes("UTF-8")));
}

public static void main(String [] args) throws Exception {
  System.out.println(encode("key", "The quick brown fox jumps over the lazy dog"));
}

Ou vous pouvez retourner le hachage encodé en Base64 :

 Base64.encodeBase64String(sha256_HMAC.doFinal(data.getBytes("UTF-8")));

La sortie en hexadécimal est comme prévu :

 f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

44voto

LastCoder Points 10027

Le 0x indique simplement que les caractères après représentent une chaîne hexadécimale.

 0x1A == 1Ah == 26 == 1A

Donc, le 0x sert juste à clarifier dans quel format se trouve la sortie, pas besoin de s'en soucier.

24voto

user210791 Points 26

Si vous utilisez Guava, sa dernière version vous permet désormais d'utiliser

  Hashing.hmacSha256()

Un exemple d'utilisation de ceci :

 String hash = Hashing.hmacSha256("mykey".getBytes(StandardCharsets.UTF_8)).hashString("my_message", StandardCharsets.UTF_8).toString()

Plus de documentation ici : https://guava.dev/releases/23.0/api/docs/com/google/common/hash/Hashing.html#hmacSha256-byte:A-

14voto

Michael Points 822

La réponse que vous y avez obtenue est correcte. Une chose mineure dans le code ci-dessus, vous devez init (clé) avant de pouvoir appeler doFinal ()

     final Charset charSet = Charset.forName("US-ASCII");
    final Mac sha256_HMAC = Mac.getInstance("HmacSHA256");

    final SecretKeySpec secret_key = new javax.crypto.spec.SecretKeySpec(charSet.encode("key").array(), "HmacSHA256");
    try {
        sha256_HMAC.init(secret_key);
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    ...

12voto

Bikesh M Annur Points 3899

Cela fonctionne bien pour moi

j'ai ajouter une dépendance

 compile 'commons-codec:commons-codec:1.9'

réf : http://mvnrepository.com/artifact/commons-codec/commons-codec/1.9

ma fonction

 public String encode(String key, String data) {
    try {

        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
        sha256_HMAC.init(secret_key);

        return new String(Hex.encodeHex(sha256_HMAC.doFinal(data.getBytes("UTF-8"))));

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    return null;
}

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:

X