PHP验签JWT RS256

作者在 2021-04-30 14:52:02 发布以下内容

踩坑 PHP验签JWT RS256

使用openssl_verify验签时总是报错


error:04091077:rsa routines:int_rsa_verify:wrong sart line
或者



error:04091077:rsa routines:int_rsa_verify:wrong signature length
对比一圈类库,发现需要满足如下几个条件:


1. 公钥必须按64位换行


$pubkey = file_get_contents("./pubkey");
$search = [
    "-----BEGIN PUBLIC KEY-----",
    "-----END PUBLIC KEY-----",
    "\n",
    "\r",
    "\r\n"
];
$public_key=str_replace($search,"",$pubkey);
$public_key=$search[0] . PHP_EOL . chunk_split($public_key, 64,"\n") . $search[1];


2. 签名base64_decode前必须将Byte数使用=号补齐4的倍数

function urlsafeB64Decode($sign)
{
    $remainder = \strlen($sign) % 4;
    if ($remainder) {
        $padlen = 4 - $remainder;
        $input .= \str_repeat('=', $padlen);
    }
    return \base64_decode(\strtr($sign, '-_', '+/'));
}
3. 验签的数据不是整个jwt串,而是header+"."+payload,并不包含sign



$result = openssl_verify("$tokenarr[0].$tokenarr[1]", urlsafeB64Decode($sign), $res, OPENSSL_ALGO_SHA256);


注:“encoding/base64” 提供了四种编码和解码的方法:

  • StdEncoding , 常规编码,bit不足 3 倍时,使用 0 补齐。Byte不足4倍时,使用=补齐
  • URLEncoding , URL safe 编码,替换掉字符串中的特殊字符 +/ 转化成 -_
  • RawStdEncoding , 常规编码,末尾不补 =
  • RawURLEncoding , URL safe 编码,末尾不补 =


附整体示例:


<?php
$token = "RS256 jwt串";
$tokenarr = explode(".",$token);
$sign = $tokenarr[2];
$pubkey = file_get_contents("./pubkey");
$search = [
    "-----BEGIN PUBLIC KEY-----",
    "-----END PUBLIC KEY-----",
    "\n",
    "\r",
    "\r\n"
];
$public_key=str_replace($search,"",$pubkey);
$public_key=$search[0] . PHP_EOL . chunk_split($public_key, 64,"\n") . $search[1];
$res = openssl_get_publickey($public_key);
if($res){
    $result = openssl_verify("$tokenarr[0].$tokenarr[1]", urlsafeB64Decode($sign), $res, OPENSSL_ALGO_SHA256);
    openssl_free_key($res);
    if(!$result){
        var_dump(openssl_error_string());die();
    }
    var_dump($result);
}


function urlsafeB64Decode($input)
{
    $remainder = \strlen($input) % 4;
    if ($remainder) {
        $padlen = 4 - $remainder;
        $input .= \str_repeat('=', $padlen);
    }
    return \base64_decode(\strtr($input, '-_', '+/'));
}


PHP | 阅读 1083 次
文章评论,共0条
游客请输入验证码
文章分类
文章归档
最新评论