当前位置: 首页 > 知识库问答 >
问题:

在JWT令牌创建过程中了解RS256和SHA256

吕胤
2023-03-14

我正在PHP中使用私钥创建一个JWT令牌。为此,我使用OpenSSL库。在任何事情之前,我将共享我的代码:

PHP

    $header = [
        self::ALG => self::RS256,
        self::TYP => self::JWT
    ];
    $payload = [
        "iss" => $this->getClientID(),
        "iat" => time(),
        "exp" => time()+999
    ];
    $header = base64_encode(json_encode($header));
    $payload = base64_encode(json_encode($payload));
    $token = $header.".".$payload;
    $pkey = openssl_pkey_get_private($this->getPrivateKey(), $this->getPassPhrase());
    openssl_sign($token, $signature, $pkey, 'sha256'); //no algorithm specifically for rs256
    $sign = base64_encode($signature);
    return $token.".".$sign;

所以,这个JWT令牌将用于我试图访问的服务器中的身份验证。但我从外部服务器得到的响应是一个错误的请求,我的JWT令牌创建中出现了问题。

使用相同的凭据,我使用库jsrsasign尝试了javascript,然后它给了我正确的响应。

JAVASCRIPT中文

// Header
var oHeader = { alg: 'RS256', typ: 'JWT' };
// Payload
var oPayload = {};
var tNow = rs.KJUR.jws.IntDate.get('now');
var tEnd = tNow + 1000;
oPayload.iss = "playground.pizza";
oPayload.iat = tNow;
oPayload.exp = tEnd;
var sHeader = JSON.stringify(oHeader);
var sPayload = JSON.stringify(oPayload);
var pkey = "my private key" //I replaced all the new line with \n here and had in one line
var prvKey = rs.KEYUTIL.getKey(pkey, "my_pass_phrase");
var sJWT = rs.KJUR.jws.JWS.sign("RS256", sHeader, sPayload, prvKey);
ultraSecureToken = sJWT;

我可以清楚地看到的一个区别是,对于php端的签名生成函数,我将sha256作为算法传递,而在JavaScriptRS256中传递。

我读到过sha256只是一个散列算法,RS256用于编码,但是在我在php中找到的所有库中,它们只在openssl_sign函数中内部传递sha256openssl_sign没有RS256作为算法参数。

所以,首先,我哪里出了问题。

其次,有没有一种方法可以在php中使用RS256生成签名。

PS:我正在寻找php的解决方案。

共有1个答案

孔鹤龄
2023-03-14

>

  • KJUR的返回值。jws。JWS。符号由点分隔的三部分组成。第一部分是Base64url编码的JSON字符串,第二部分是Base64url编码的JSON字符串,第三部分是Base64url编码的签名。要签名的数据包括前两部分,包括分隔这两部分的点。RS256表示签名使用带有RSASSA-PKCS1-v1\u 5填充的SHA256和RSA。这也可以很容易地在网上进行验证,例如在这里,可以选择SHA256withRSA作为算法。

    openssl_sign还使用带有RSASSA-PKCS1-v1_5填充的RSA,因此使用SHA256创建相同的签名,假设应用了相同的密钥和要签名的相同数据。

    jsrsasign使用Base64 url编码(RFC4648,第5节),而PHP(或者更准确地说是Base64\u编码方法)使用标准Base64编码(RFC4648,第4节),这很可能是问题的原因之一。这意味着当前PHP代码中的编码必须更改为Base64url,例如此处。

    当然,PHP代码中的底层JSON字符串($header$payload$token)也必须与JavaScript代码中的对应字符串相同,否则签名会有所不同。由于PHP代码不完整,因此无法检查,这可能是问题的另一个原因。

  •  类似资料:
    • 我试图仅使用bash和openSSL构建一个RS256 JWT令牌(我的开发工具有限)。 我设计了一个脚本,它从txt文件中获取标头和有效负载(删除换行符等),base 64URL对它们进行编码并将它们与“.”分隔符连接在一起。 然后我尝试对输出进行签名,我还对输出进行了base-64URL编码并附加到末尾(使用另一个“.”分隔符)。我相信这准确地反映了JWT模型。 我的私钥和证书是使用openS

    • 我正在尝试使用JWT创建一个演示/测试RS256 JWT。IO网站。每次我尝试在该网站上创建JWT时,它都会说签名无效。 签名公钥由网站自动提供 有什么我错过的把戏吗? 旁注1:我已经删除了值,因为我不确定这是否敏感...即使这只是一些蹩脚的演示JWT学习/实验。 旁注2:我实际上在使用Auth0进行委托身份验证。我有一个完整的RS256令牌,Auth0已经给了我。。。并且可以在JWT中显示。我。

    • 我使用了一个JWT(Json Web令牌),它在负载中有一个刷新令牌(GUID)。通常,我使用Firebase JWT创建/编码和解码JWT。 我想在PHP中解码一个过期的JWT,然后使用其负载中的刷新令牌创建一个新的JWT(只要刷新令牌仍然有效)。如果我用Firebase解码JWT,它会抛出一个异常(过期),并且不会返回解码后的令牌。 如何安全地解码过期的JWT并访问它的有效负载?我可以只捕获过

    • 问题内容: 我目前正在使用Golang应用程序。我从客户端收到JWT令牌,在Go中,我需要对该令牌进行解码并获取以下信息:用户,名称等。我正在检查可用于处理JWT的库令牌,我来到https://github.com/dgrijalva/jwt- go ,但我看不到如何简单地制作所需的东西。 我有令牌,我需要将信息解码为地图或至少为json。在哪里可以找到如何做的指南?谢谢! 问题答案: 函数接受第

    • 我需要与GitHub集成API进行交互,但具体是从。NET 4.0,所以我不能使用Octokit。 基本上,我得到了一个格式化的私有rsa密钥(标准不支持。NET API),并且必须发送RS256 jwt令牌才能获得与API交互的身份验证令牌。 提供了以下ruby示例代码: 使用下面的curl示例 以及以下Result示例:

    • 我使用jsonwebtoken解码我的令牌,看看它是否已过期。但是,控制台.log返回 null。 我不明白,因为我的令牌不为空