Java的字符串是unicode编码,不受源码文件的编码影响;而PHP的编码是和源码文件的编码一致,受源码编码影响。
PHP文档中的hash_hmac的声明:
string hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = FALSE ] )
algo
要使用的哈希算法名称,例如:"md5","sha256","haval160,4" 等。 如何获取受支持的算法清单,请参见 hash_algos()。
data
要进行哈希运算的消息。
key
使用 HMAC 生成信息摘要时所使用的密钥。
raw_output 设置为 TRUE 输出原始二进制数据, 设置为 FALSE 输出小写 16 进制字符串。
在Java中sha256HMAC后得到的值为二进制,So,PHP也要转换为二进制,所以改进为以下代码:hash_hmac("sha256", $signPlanText, $appSecret,true);//由此生成出的为二进制格式
这还没完,最重要的出现了:
java中Base64.encodeBase64URLSafeString(bytes) 会将 特殊字符‘+/’替换为'-_',会将‘=’去掉
但是!!PHP不会!!! PHP 没有提供url安全的base64编码函数,需要自己手动去撸!还是自己水平不够
So,出现了以下代码,也是最终的解决方案:/**
* 签名验证
*/
public static function generateSHASign($signPlanText,$appSecret){
$signature = self::base64UrlEncode(hash_hmac("sha256",$signPlanText, $appSecret, true));
return $signature;
}
/**
* 替换特殊符号
*/
public static function base64UrlEncode($str){
return rtrim(strtr(base64_encode($str),'+/','-_'),'=');
}
文献参考地址https://blog.csdn.net/weixin_33970449/article/details/88655285