JavaScript通过CryptoJS等效实现php中hash_hmac函数加密raw_output配置

在一个项目中,客户需要从前端签名,加密插件使用的cryptoJS,使用与后端一样的签名流程(HmacSHA1Base64.encode)发现并不能通过签名认证,签名校验方后端php代码中使用hash_hmac函数,先来看一下则会个函数的官网说明:

说明
hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = FALSE ] ) : string

参数
algo
要使用的哈希算法名称,例如:"md5","sha256","haval160,4" 等。 如何获取受支持的算法清单,请参见 hash_hmac_algos() 函数。
data
要进行哈希运算的消息。
key
使用 HMAC 生成信息摘要时所使用的密钥。
raw_output
设置为 TRUE 输出原始二进制数据, 设置为 FALSE 输出小写 16 进制字符串

返回值
如果 raw_output 设置为 TRUE, 则返回原始二进制数据表示的信息摘要, 否则返回 16 进制小写字符串格式表示的信息摘要。 如果 algo 参数指定的不是受支持的算法,返回 FALSE。

api接口加密签名代码:

/**
  * @param $uri string 请求URL的path部分,如'v1/task/index'
  * @param $appkey string 应用appkey
  * @param $secret string 应用secret
  * @param $timestamp int 时间戳
  * @return string
  */
private static function generateSign($uri, $appkey, $secret, $timestamp)
{
    $str = $uri . '_' . $appkey . '_' . $timestamp;
    if (function_exists('hash_hmac')) {
        return base64_encode(hash_hmac("sha1", $str, $secret, true));
    } else {
        return '';
    }
}

可以看到加密函数hash_hmacraw_output设置了true,及加密返回的是原始二进制数据表示的信息摘要,那么在前端这边使用CryptoJS如果达到同样的效果呢?

经过测试,这样的代码可以实现:

首先,引入CryptoJS包中的三个文件core-min.jshmac-sha1.jsenc-base64-min.js,签名代码:

function getSign(uri, appkey, secret, timestamp){
    var str = uri + '_' + appkey + '_' + timestamp;
    var hash = CryptoJS.HmacSHA1(str, secret);       
    var base64 = hash.toString(CryptoJS.enc.Base64);
    console.log(base64);
    return base64;
}

这样生成的签名就可以通过校验了。

CryptoJS包下载见项目:sytelus/CryptoJS

发表评论

电子邮件地址不会被公开。 必填项已用*标注