在创建 JWT 令牌期间了解 RS256 和 SHA256
Understanding RS256 and SHA256 during JWT Token creation
我正在 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 令牌将用于我尝试访问的服务器中的身份验证。但是我从外部服务器得到的响应是 Bad Request
,我的 JWT 令牌创建过程中出现了问题。
使用相同的凭据,我在 javascript 中尝试使用库 jsrsasign
,然后它给了我正确的响应。
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 端的 signature generation function
,我将 sha256
作为算法传递,而在 JavaScript RS256
通过了。
我了解到 sha256 只是一种哈希算法,而 RS256 用于编码,但在我在 php 中找到的所有库中,它们仅在 [=] 中内部传递 sha256
18=] 函数。并且openssl_sign
没有RS256作为算法参数。
所以,首先我哪里出错了。
其次,有没有一种方法可以在php中使用RS256生成签名。
PS :我正在 php.
中寻找解决方案
KJUR.jws.JWS.sign
consists of three portions separated by a dot. The first part is the Base64url-encoded JSON-string sHeader
, the second part is the Base64url-encoded JSON-string sPayload
and the third part is the Base64url-encoded signature. The data to be signed consist of the first two portions including the dot separating the two portions. RS256 means that SHA256 and RSA with RSASSA-PKCS1-v1_5 padding is used for the signature. This can also be easily verified online, e.g. here 的 return 值,由此选择 SHA256withRSA
作为算法。
假定相同的密钥和应用相同的待签名数据。
jsrsasign
使用 Base64 url-encoding (RFC4648, sect. 5), while PHP (or more precisely the base64_encode
-method) uses standard Base64-encoding (RFC4648, sect. 4), which most likely is one cause of the issue. This means that the encoding in the current PHP-code must be changed to Base64url, e.g. here.
当然,PHP-代码中的底层 JSON-字符串($header
、$payload
和 $token
)也必须与 JavaScript 代码中的对应项相同,否则签名将不同。由于 PHP-代码不完整,无法检查,这可能是问题的另一个原因。
我正在 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 令牌将用于我尝试访问的服务器中的身份验证。但是我从外部服务器得到的响应是 Bad Request
,我的 JWT 令牌创建过程中出现了问题。
使用相同的凭据,我在 javascript 中尝试使用库 jsrsasign
,然后它给了我正确的响应。
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 端的 signature generation function
,我将 sha256
作为算法传递,而在 JavaScript RS256
通过了。
我了解到 sha256 只是一种哈希算法,而 RS256 用于编码,但在我在 php 中找到的所有库中,它们仅在 [=] 中内部传递 sha256
18=] 函数。并且openssl_sign
没有RS256作为算法参数。
所以,首先我哪里出错了。
其次,有没有一种方法可以在php中使用RS256生成签名。
PS :我正在 php.
中寻找解决方案KJUR.jws.JWS.sign
consists of three portions separated by a dot. The first part is the Base64url-encoded JSON-stringsHeader
, the second part is the Base64url-encoded JSON-stringsPayload
and the third part is the Base64url-encoded signature. The data to be signed consist of the first two portions including the dot separating the two portions. RS256 means that SHA256 and RSA with RSASSA-PKCS1-v1_5 padding is used for the signature. This can also be easily verified online, e.g. here 的 return 值,由此选择SHA256withRSA
作为算法。
假定相同的密钥和应用相同的待签名数据。
jsrsasign
使用 Base64 url-encoding (RFC4648, sect. 5), while PHP (or more precisely thebase64_encode
-method) uses standard Base64-encoding (RFC4648, sect. 4), which most likely is one cause of the issue. This means that the encoding in the current PHP-code must be changed to Base64url, e.g. here.当然,PHP-代码中的底层 JSON-字符串(
$header
、$payload
和$token
)也必须与 JavaScript 代码中的对应项相同,否则签名将不同。由于 PHP-代码不完整,无法检查,这可能是问题的另一个原因。