java équivalent à HMAC-SHA1 de php

Je cherche un équivalent java à cet appel php:

hash_hmac('sha1', "test", "secret")

J'ai essayé ceci, en utilisant java.cryptographique.Mac, mais les deux ne sont pas d'accord:

String mykey = "secret";
String test = "test";
try {
    Mac mac = Mac.getInstance("HmacSHA1");
    SecretKeySpec secret = new SecretKeySpec(mykey.getBytes(),"HmacSHA1");
    mac.init(secret);
    byte[] digest = mac.doFinal(test.getBytes());
    String enc = new String(digest);
    System.out.println(enc);  
} catch (Exception e) {
    System.out.println(e.getMessage());
}

Les sorties avec key = "secret" et de test = "test" ne semblent pas correspondre.

47
demandé sur Juha Syrjälä 2009-10-23 00:56:57

7 réponses

En fait, ils ne l'acceptent.
Comme Hans Doggen l'a déjà noté, PHP affiche le résumé des messages en utilisant la notation hexadécimale, sauf si vous définissez le paramètre de sortie brut sur true.
Si vous souhaitez utiliser la même notation en Java, vous pouvez utiliser quelque chose comme

for (byte b : digest) {
    System.out.format("%02x", b);
}
System.out.println();

Pour formater la sortie en conséquence.

37
répondu Dirk D 2009-10-22 22:28:15

Vous pouvez essayer ceci en Java:

private static String computeSignature(String baseString, String keyString) throws GeneralSecurityException, UnsupportedEncodingException {

    SecretKey secretKey = null;

    byte[] keyBytes = keyString.getBytes();
    secretKey = new SecretKeySpec(keyBytes, "HmacSHA1");

    Mac mac = Mac.getInstance("HmacSHA1");

    mac.init(secretKey);

    byte[] text = baseString.getBytes();

    return new String(Base64.encodeBase64(mac.doFinal(text))).trim();
}
14
répondu dharan 2011-05-25 17:56:26

C'est mon implémentation:

        String hmac = "";

    Mac mac = Mac.getInstance("HmacSHA1");
    SecretKeySpec secret = new SecretKeySpec(llave.getBytes(), "HmacSHA1");
    mac.init(secret);
    byte[] digest = mac.doFinal(cadena.getBytes());
    BigInteger hash = new BigInteger(1, digest);
    hmac = hash.toString(16);

    if (hmac.length() % 2 != 0) {
        hmac = "0" + hmac;
    }

    return hmac;
5
répondu atomsfat 2011-05-11 18:40:21

Me semble que PHP utilise la notation hexadécimale pour les octets que Java produit ( 1a = 26) - Mais je n'ai pas vérifié toute l'expression.

Que se passe-t-il si vous exécutez le tableau d'octets via la méthode sur cette page?

3
répondu Hans Doggen 2009-10-22 21:30:04

Mon implémentation pour HmacMD5-il suffit de changer l'algorithme en hmacsha1:

SecretKeySpec keySpec = new SecretKeySpec("secretkey".getBytes(), "HmacMD5");
Mac mac = Mac.getInstance("HmacMD5");
mac.init(keySpec);
byte[] hashBytes = mac.doFinal("text2crypt".getBytes());
return Hex.encodeHexString(hashBytes);
2
répondu Krizko 2013-05-13 11:03:19

Ne l'ont pas testé, mais essayez ceci:

        BigInteger hash = new BigInteger(1, digest);
        String enc = hash.toString(16);
        if ((enc.length() % 2) != 0) {
            enc = "0" + enc;
        }

C'est un instantané de ma méthode qui fait que les md5 et sha1 de java correspondent à php.

1
répondu serg 2009-10-22 21:30:58

De cette façon, je pourrais obtenir exactement la même chaîne que je recevais avec hash_hmac en php

String result;

try {
        String data = "mydata";
        String key = "myKey";
        // 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(data.getBytes());

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

        //  Covert array of Hex bytes to a String
        result = new String(hexBytes, "ISO-8859-1");
        out.println("MAC : " + result);
}
catch (Exception e) {

}
1
répondu Akhil 2014-10-10 10:06:26