PHP中的HMAC输出与Java中的HMAC输出不匹配

时间:2019-02-02 05:54:32

标签: java php hmac

我正在尝试建立一个需要HMAC和加密的API连接。 给我的文档和示例输出/代码使用Java,但我的网站使用PHP。我在PHP 7。

我应该怎么做才能使我的PHP输出与API文档中给出的Java示例输出中的输出相匹配?

我已经尝试在PHP hmac输出上对base64,utf8和utf16进行编码,但仍然不匹配。

PHP代码:

$sb = '4a275929e0eba4445bc7f9a80c6361a2351119a27b51eebb2c259f68f72efd5f';
$keyToEncode = 'c0814229c201ab1022070741d15eda7af2189db64a2c88699c6481dbb83521afd8640d9af6d984602037d2e4f90c4f9a12915899290d944f385192b658829ec1;
$sb3 = hash_hmac('sha256',$sb, $keyToEncode);

Java代码

HMAC_SHA256(sb.toString(), keyToEncode);

输出在PHP:

2bea1f99897a8fd2e836e9d8f7820a28c03b76bf37daf04527f6f5d279c97fd7

Java的预期输出:

gWzlCNzu7fNN4z/uwvrgk574dTJqLQ8+25UMXCh+4tU=

1 个答案:

答案 0 :(得分:0)

以下PHP代码从Java代码复制结果:

<?php
$sb = 'c0814229c201ab1022070741d15eda7af2189db64a2c88699c6481dbb83521afd8640d9af6d984602037d2e4f90c4f9a12915899290d944f385192b658829ec1';
$keyToEncode = '4a275929e0eba4445bc7f9a80c6361a2351119a27b51eebb2c259f68f72efd5f';
$sb3 = hash_hmac('sha256',$sb, $keyToEncode); // HMAC-value as lowercase hexadecimal string
$sb4 = hex2bin($sb3);                         // HMAC-value as binary data  
$sb5 = base64_encode($sb4);                   // Base64-encoded HMAC-value 
print "HMAC-value (hexadecimal string): ".$sb3."\n"."HMAC-value (Base64-encoded): ".$sb5; 

具有以下输出:

HMAC-value (hexadecimal string): 816ce508dceeedf34de33feec2fae0939ef875326a2d0f3edb950c5c287ee2d5
HMAC-value (Base64-encoded): gWzlCNzu7fNN4z/uwvrgk574dTJqLQ8+25UMXCh+4tU=

$sb5是与Java代码结果相对应的Base64编码的HMAC值。

您的代码有两个缺陷:

  1. 为值$sb$keyToEncode进行混淆。
  2. PHP方法hash_mac具有第四个参数$raw_output,默认情况下为FALSE。设置为FALSE时,结果以小写十六进制字符串的形式返回,否则以 binary data http://php.net/manual/en/function.hash-hmac.php)的形式返回。因为你的PHP-代码使用的$raw_output(即FALSE),所述HMAC返回为一个十六进制字符串,默认值和必须首先被转换为二进制数据之前其可以是Base64编码。为了进行转换,必须使用PHP方法hex2bin

顺便说一句,您也可以使用$raw_output = TRUE变体。然后,无需使用hex2bin进行转换。但是,如果要将HMAC显示为十六进制字符串,则必须使用PHP方法bin2hex

<?php
$sb = 'c0814229c201ab1022070741d15eda7af2189db64a2c88699c6481dbb83521afd8640d9af6d984602037d2e4f90c4f9a12915899290d944f385192b658829ec1';
$keyToEncode = '4a275929e0eba4445bc7f9a80c6361a2351119a27b51eebb2c259f68f72efd5f';
$sb3 = hash_hmac('sha256',$sb, $keyToEncode, TRUE); // HMAC-value as binary data
$sb4 = base64_encode($sb3);                         // Base64-encoded HMAC-value
print "HMAC-value (hexadecimal string): ".bin2hex($sb3)."\n"."HMAC-value (Base64-encoded): ".$sb4; 

具有与上述相同的输出。

$sb4是与Java代码结果相对应的Base64编码的HMAC值。