JWT使用RSA计算签名SHA256



我正在尝试

使用SHA256withRSA对输入的UTF-8表示形式进行签名(同样称为带有SHA-256散列函数的RSASSA-PKCS1-V1_5-SIGN)从API控制台获得的私钥。输出将是字节数组。

所以让我们取Header和Claim集合,并将它们放入数组中

{"alg":"RS256","typ":"JWT"}.
{
  "iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope":"https://www.googleapis.com/auth/prediction",
  "aud":"https://accounts.google.com/o/oauth2/token",
  "exp":1328554385,
  "iat":1328550785
}

就像服务帐户:计算签名

JSON Web签名(JWS)是指导生成JWT签名的机制签名的输入是以下内容的字节数组

Base64url编码的标头}。{Base64url编码索赔集}

所以我构建阵列只是为了测试

  $seg0 = array(
    "alg" => "RS256",
    "typ" => "JWT"
  );
  $seg1 = array(
    "iss" => "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
    "scope" => "https://www.googleapis.com/auth/prediction",
    "aud" => "https://accounts.google.com/o/oauth2/token",
    "exp" => 1328554385,
    "iat" => 1328550785
  );
  $segs = array(
    json_encode($seg0),
    stripslashes(json_encode($seg1))
  );
  $segments = array(
    rtrim(strtr(base64_encode($segs[0]), '+/', '-_'), '='),
    rtrim(strtr(base64_encode($segs[1]), '+/', '-_'), '='),
  );

就是这样。前2个数组编码成功。

Output
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ

我继续对签名进行编码

然后签名必须是Base64url编码的。然后签名与"."连接Base64url末尾的字符输入字符串的表示形式。结果就是JWT。它应该如下所示:
Base64url编码的标头}。{Base64url编码的声明集}。{Base64url编码签名}

  $signature = makeSignedJwt($segments);
  //$signature = makeSignedJwt($segs);
  echo $signature .'<br /><br />';
  $segments[] = rtrim(strtr(base64_encode($signature), '+/', '-_'), '=');
  echo '<pre>'; print_r($segments); echo '</pre>';  
function makeSignedJwt($segments)
{
    $data = implode('.', $segments);
    if (!openssl_sign($data, $signature, privateKey, "sha256"))
    {
        exit("Unable to sign data");
    }
    return $signature;
}
Output
    Array
(
    [0] => eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
    [1] => eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ
    [2] => xFS6iZdJku5RKJ5_XdH3W5A8e9V3wsaFeQhAXoJtuxzW-xvqZq1CdEJJAo60VvK1UFONElVf_pthezEyz-eyWsoRGVZFibUQBaKXLI8eR28eFlaCAKH7bKh820uR7IwuRx4xr8MPmnC8so9u9TEY153gkU6Mz9e--pQPlcLlGY
)

一定是遗漏了什么。。

我不确定你的问题是什么,但以下对我有效:

//helper function
function base64url_encode($data) { 
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); 
}
//Google's Documentation of Creating a JWT: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests
//{Base64url encoded JSON header}
$jwtHeader = base64url_encode(json_encode(array(
    "alg" => "RS256",
    "typ" => "JWT"
)));
//{Base64url encoded JSON claim set}
$now = time();
$jwtClaim = base64url_encode(json_encode(array(
    "iss" => "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
    "scope" => "https://www.googleapis.com/auth/prediction",
    "aud" => "https://www.googleapis.com/oauth2/v4/token",
    "exp" => $now + 3600,
    "iat" => $now
)));
//The base string for the signature: {Base64url encoded JSON header}.{Base64url encoded JSON claim set}
openssl_sign(
    $jwtHeader.".".$jwtClaim,
    $jwtSig,
    $your_private_key_from_google_api_console,
    "sha256WithRSAEncryption"
);
$jwtSig = base64url_encode($jwtSig);
//{Base64url encoded JSON header}.{Base64url encoded JSON claim set}.{Base64url encoded signature}
$jwtAssertion = $jwtHeader.".".$jwtClaim.".".$jwtSig;

最新更新