Frage

Ich suche einen Java -Äquivalent mit diesem PHP -Anruf:

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

Ich habe es versucht und benutze java.crypto.mac, aber die beiden sind sich nicht einig:

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

Die Ausgänge mit Key = "Secret" und Test = "Test" scheinen nicht übereinstimmen.

War es hilfreich?

Lösung

Tatsächlich stimmen sie zu.
Wie Hans Dobgen bereits feststellte, gibt PHP den Meldungsdigest mithilfe von Hexadezimalnotation aus, es sei denn, Sie setzen den RAW -Ausgangsparameter auf True.
Wenn Sie dieselbe Notation in Java verwenden möchten, können Sie so etwas wie verwenden

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

die Ausgabe entsprechend formatieren.

Andere Tipps

Sie können dies in Java versuchen:

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

Dies ist meine Implementierung:

        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;

Mir scheint, dass PHP Hex -Notation für die Bytes verwendet, die Java produziert (1a = 26) - aber ich habe den gesamten Ausdruck nicht überprüft.

Was passiert, wenn Sie das Byte -Array durch die Methode aufführen Dies Seite?

Meine Implementierung für HMACMD5 - Ändern Sie einfach den Algorithmus in 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);

Ich habe es nicht getestet, aber versuchen Sie es mit:

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

Dies ist Schnappschuss aus meiner Methode, die dazu führt, dass Javas MD5 und SHA1 PHP passen.

Auf diese Weise konnte ich genau die gleiche Zeichenfolge bekommen wie ich mit Hash_HMAC in PHP bekam

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

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top