it-swarm.com.de

HMAC-SHA1: Wie mache ich das richtig in Java?

Ich benutze einige Werte mit HMAC-SHA1 und verwende den folgenden Code in 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() gehört zu org.Apache.commons.codec

In PHP gibt es eine ähnliche Funktion hash_hmac(algorithm, data, key), die ich zum Vergleichen der von meiner Java-Implementierung zurückgegebenen Werte verwende.

Der erste Versuch ist also:

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

das gibt zurück: 74ae5a4a3d9996d5918defc2c3d475471bbf59ac

Meine Java-Funktion gibt ebenfalls 74ae5a4a3d9996d5918defc2c3d475471bbf59ac zurück.

Ok, es scheint zu funktionieren. Dann versuche ich einen komplexeren Schlüssel zu verwenden:

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

das gibt zurück: e98bcc5c5be6f11dc582ae55f520d1ec4ae29f7a

Während dieser Zeit gibt mein Java-Impl Folgendes zurück: c19fccf57c613f1868dd22d586f9571cf6412cd0

Der von meinem PHP -Code zurückgegebene Hash entspricht nicht dem von meiner Java-Funktion zurückgegebenen Wert, und ich kann den Grund dafür nicht herausfinden.

Irgendwelche Tipps?

50
Mark

Verwenden Sie auf Ihrer PHP Seite einfache Anführungszeichen um den Schlüssel, damit das $-Zeichen nicht als Variablenreferenz behandelt wird. d.h.

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

Ansonsten ist der Schlüssel wirklich PRIE7-Yf17kEnUEpi5hvW/#AFo (vorausgesetzt, die Variable $oG2uS ist nicht definiert).

50

Empfehlen Apache Common Codec Library , recht einfach und benutzerfreundlich .HmacUtils.hmacSha1Hex(key, string_to_sign);

15
Armstrongya

Jedes $ -Zeichen in Anführungszeichen ("") wird in PHP als Variable betrachtet. Sie können den Fehler vermeiden, indem Sie entweder einfache Anführungszeichen verwenden, wie im vorherigen Kommentar angegeben, oder Sie können das Dollarzeichen wie folgt umgehen

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

Hinweis $ ist jetzt\$

7
tlogbon

In Java und Verwendung von maven :

Fügen Sie die folgende Abhängigkeit in den pom.xml ein:

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

und dann versuchen Sie es mit diesem zu signieren

HmacUtils.hmacSha1Hex(key, string_to_sign);
1

Die anderen Antworten, die auf HmacUtils von Apache Commons hinweisen, sind mittlerweile veraltet. Apache Commons empfiehlt jetzt die Verwendung von:

new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(string_to_sign)

1
mouse_8b