PHP的hash_hmac签名加密,JWT

记一次对接第三方用到 JWT bearer tokens;HS512签名算法。
JWT官网

    /**
     * 测试
     */
    public function gztest()
    {
        $appId = '4247518988';
        $appSecret = 'YGxIx/Bw+ZvaoEAV5DtS1pWrG5tmYDIYSALxH1jVcPJyH6y/3b5A8lF3j05jXNZ/vgznOf1XprTyfoIoR4HnmA==';
        $timestamp = 1575943037;

        $token = self::getToken($appId, $appSecret, $timestamp);
        return $token;
    }

    /**
     * 生成JWT Token
     */
    public static function getToken($appId, $appSecret, $timestamp)
    {
        $header = [
            'alg' => 'HS512',
            'typ' => 'JWT'
        ];
        $header = json_encode($header);
        $payload = [
            'sub' => $appId,
            'iat' => $timestamp,
        ];
        $payload = json_encode($payload);

        //base64UrlEncode加密
        $data = self::base64url_encode($header).'.'.self::base64url_encode($payload);
        $shaKey = base64_decode($appSecret);

        //按文档 - 对传入参数进行HMAC-SHA512加密
        //HMACSHA512(base64UrlEncode(header) + "." + base64UrlEncode(payload), base64Decode(secret))
        $signature = self::getSignByHmac($data, $shaKey);

        //按文档 - 得到Token
        //base64UrlEncode(header) + "." + base64UrlEncode(payload) + "." + base64UrlEncode(verify_signature)
        $token = $data.'.'.$signature;

        return $token;
    }
    /**
     * 签名验证
     * @param $data     要进行哈希运算的消息。
     * @param $shakey   使用 HMAC 生成信息摘要时所使用的密钥。
     */
    public static function getSignByHmac($data, $shaKey)
    {
        $get_signature = hash_hmac('sha512', $data, $shaKey, true); //PHP要转换为二进制
        $signature = self::base64url_encode($get_signature);
        return $signature;
    }
    /**
     * 替换特殊符号
     * php的base64_encode和base64_decode用来转换url是不符合要求,所以需要自己实现方法
     * java中Base64.encodeBase64URLSafeString(bytes) 会将 特殊字符‘+/’替换为'-_',会将‘=’去掉
     * 但是!!PHP不会!!! PHP 没有提供url安全的base64编码函数。
     *
     * 参考:https://blog.csdn.net/weixin_33970449/article/details/88655285
     */
    public static function base64url_encode($data)
    {
        return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
    }
    public static function base64url_decode($data)
    {
        return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
    }


    // CURL实现的post方法请求
    public static function curl_post($url, $post_data, $jwtToken = '')
    {
        //设置 header 参数
        $headers = array();
        $headers[] = "Accept:application/json";
        if (!empty($jwtToken)){
            $headers[] = "Authorization: Bearer " . $jwtToken;
        }

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        //设置 header 参数
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验 SSL
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60); //设置超时
        set_time_limit(0);
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }

image.png

权益
许可协议: CC BY-NC 4.0
版权所有:Copyright 2020 gz.supergz.cn
联系邮箱:gzqq23@163.com
ICP 备案:豫ICP备18024085号-2
统计
文章总数:12
访问人次:688
访问总量:5192
随言碎语:3
//