web-dev-qa-db-ja.com

HMAC-SHA1:Javaで適切に行う方法

Javaで次のコードを使用して、HMAC-SHA1を使用していくつかの値をハッシュしています。

_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()は_org.Apache.commons.codec_に属します

PHP)には、同様の関数hash_hmac(algorithm, data, key)があり、これを使用して、Java実装。

したがって、最初の試行は次のとおりです。

_hash_hmac("sha1", "helloworld", "mykey") // PHP
_

返される値:_74ae5a4a3d9996d5918defc2c3d475471bbf59ac_

My Java関数は_74ae5a4a3d9996d5918defc2c3d475471bbf59ac_も返します。

うまくいきました。次に、より複雑なキーを使用しようとします:

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

返される値:_e98bcc5c5be6f11dc582ae55f520d1ec4ae29f7a_

今回はmy Java implが返します:_c19fccf57c613f1868dd22d586f9571cf6412cd0_

My PHPコードによって返されるハッシュは、my Java関数によって返される値と等しくありません。理由はわかりません。

任意のヒント?

51
Mark

PHP側で、キーを単一引用符で囲み、$文字は変数参照として扱われません。すなわち、

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

それ以外の場合、実際に取得するキーはPRIE7-Yf17kEnUEpi5hvW/#AFo(変数$oG2uS 定義されていません)。

52

推奨 Apache Common Codec Library 、非常にシンプルで使いやすい。 HmacUtils.hmacSha1Hex(key, string_to_sign);

15
Armstrongya

二重引用符( "")で囲まれた$記号は、PHPでは変数と見なされます。前のコメント投稿者が指摘したように一重引用符を使用するか、以下のようにドル記号をエスケープすることにより、エラーを回避できます

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

$が\ $になりました

7
tlogbon

Javaで、mavenを使用:

以下の依存関係をpom.xmlに追加します。

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

そして、これを使用して署名しようとします

HmacUtils.hmacSha1Hex(key, string_to_sign);
1

Apache commonsのHmacUtilsを指す他の回答は、現在では非推奨になっています。 Apache commonsでは、次の使用を推奨しています。

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

1
mouse_8b