我正在尝试将PHP后端与Java后端集成。 Java后端需要一些必须正确编码和散列才能在两端匹配的凭证。
java系统将字符串转换为字节序列(1),然后生成该序列的HMAC / SHA256键控散列(2),然后base 64对散列(3)进行编码。
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);
或者我是否需要遍历数组并做一些魔术?
谢谢!
答案 0 :(得分:2)
我认为你不需要在php中unpack
试试
hash_hmac('sha256', $string, $secret, TRUE);
注意:我将实际字符串传递给函数,最后一个参数raw_output
设置为TRUE
<强>更新强>
你的java代码似乎错了docs
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);
答案 1 :(得分:0)
我必须在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生成的相同值。