HMAC 一个 php 字节数组


HMAC a php byte array

我正在尝试将PHP后端与Java后端集成。Java 后端需要一些凭据,这些凭据必须正确编码和哈希以在两端匹配。

Java 系统将字符串转换为字节序列 (1),然后生成该序列 (2) 的 HMAC/SHA256 键控哈希,然后对哈希 (3) 进行 base 64 编码。

private static final String HMAC_ALGORITHM = "HmacSHA256";
final SecretKey key = new SecretKeySpec('mysecret', HMAC_ALGORITHM);
final Mac hmac = Mac.getInstance(key.getAlgorithm());
hmac.init(key);
final String stringToHash = "blablabla";
final byte[] bytesToHash = stringToHash.getBytes("UTF8");
final byte[] hash = hmac.doFinal(bytesToHash);
return Base64.encodeBytes(hash);

我可以做 (1) 并将 PHP 中的字符串转换为字节序列

$stringArray = unpack('C*', $string);

在这一点上,它的工作原理并且与Java系统完全相同

但是第二部分 (2) 似乎不匹配,有没有办法在 PHP 中将字节数组传递给 hmac,因为在 Java 中,HMAC 方法接受字节数组,而 PHP 方法需要一个字符串,例如

hash_hmac('sha256', $stringArray, $secret);

还是我需要遍历数组并施展一些魔法?

谢谢!

我认为你不需要用php unpack

试试吧

hash_hmac('sha256', $string, $secret, TRUE);

注意:我正在将实际字符串传递给函数,最后一个参数raw_output设置为 TRUE

更新

您的 Java 代码似乎是错误的文档

final SecretKey key = new SecretKeySpec('mysecret', HMAC_ALGORITHM);

这应该如下所示

byte[] keyBytes = mysecret.getBytes(); // say mysecret is a String var
final SecretKey key = new SecretKeySpec(keyBytes, HMAC_ALGORITHM);

我必须在PHP上生成相同的Java值。它工作的唯一方法是这个

<?php
$verb = hash_hmac("sha256", "POST" , "9mO6oBVSmb2QTSeN73mEGHHnD", FALSE);
$path = hash_hmac("sha256", '/1.0/benefits/registerBenefit', pack("H*",  $verb), FALSE);
$query = hash_hmac("sha256", "" , pack("H*",  $path), FALSE);
$body  = hash_hmac("sha256", '{"id":"a7d23226-bdfc-4d85-a30a-b2d7eccc36e6","phone_number":"5511973512530","sku":"com.movile.cubes.br.biweekly.homolog","origin":"trade_up_group","application_id":437}' , pack("H*",  $query), FALSE);
$rawSignature   = hash_hmac("sha256", "x-kiwi-signature", pack("H*",  $body), FALSE);
$signature  = base64_encode( pack("H*",  $rawSignature));
var_dump($signature);

所以。。我不得不使用 pack("H*", $str) 来获得与 Java 生成的相同值。