HMAC-SHA1:如何在Java中正确完成?

Mar*_*ark 52 java hash sha1 hmac

我使用HMAC-SHA1散列一些值,使用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Hex() 属于 org.apache.commons.codec

在PHP中有一个类似的函数hash_hmac(algorithm, data, key),我用它来比较我的Java实现返回的值.

所以第一次尝试是:

hash_hmac("sha1", "helloworld", "mykey") // PHP
Run Code Online (Sandbox Code Playgroud)

返回: 74ae5a4a3d9996d5918defc2c3d475471bbf59ac

我的Java函数74ae5a4a3d9996d5918defc2c3d475471bbf59ac也会返回.

好吧,看起来很有效.然后我尝试使用更复杂的密钥:

hash_hmac("sha1", "helloworld", "PRIE7$oG2uS-Yf17kEnUEpi5hvW/#AFo") // PHP
Run Code Online (Sandbox Code Playgroud)

返回: e98bcc5c5be6f11dc582ae55f520d1ec4ae29f7a

虽然这次我的Java impl返回: c19fccf57c613f1868dd22d586f9571cf6412cd0

我的PHP代码返回的哈希值不等于我的Java函数返回的值,我找不到原因.

有小费吗?

Chr*_*ung 52

在PHP端,在键周围使用单引号,以便不将$字符视为变量引用.即

hash_hmac("sha1", "helloworld", 'PRIE7$oG2uS-Yf17kEnUEpi5hvW/#AFo')
Run Code Online (Sandbox Code Playgroud)

否则,你真正得到的关键是PRIE7-Yf17kEnUEpi5hvW/#AFo(假设$oG2uS未定义变量).

  • 真棒的bugfinder! (5认同)

Arm*_*gya 16

推荐Apache Common Codec Library,非常简单易用. HmacUtils.hmacSha1Hex(key, string_to_sign);

  • 已弃用。现在使用它: new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(inputStreamOfContent); (5认同)

tlo*_*bon 7

双引号("")中的任何$符号都被视为PHP中的变量.您可以通过使用前一个评论者指出的单引号来避免错误,也可以如下所示转义美元符号

hash_hmac("sha1", "helloworld", "PRIE7\$oG2uS-Yf17kEnUEpi5hvW/#AFo")
Run Code Online (Sandbox Code Playgroud)

注意$现在是\ $


小智 5

其他指出 Apache 公共资源中的 HmacUtils 的答案现在已被弃用。Apache commons 现在推荐使用:

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