首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我应该将关键对象的哪一部分传递到`openssl_verify`来验证谷歌签名的JWT?

我应该将关键对象的哪一部分传递到`openssl_verify`来验证谷歌签名的JWT?
EN

Stack Overflow用户
提问于 2014-08-01 18:25:30
回答 2查看 4.3K关注 0票数 10

我正试图用谷歌和OpenID连接来实现一个联邦登录系统,我不得不验证和解析我从谷歌获得的JWT令牌。我跟着Google文档来了。

根据docs的建议,我尝试使用现有的JWT库。GitHub上最流行的PHP版本似乎是JWT。问题似乎是JWK键的格式。

上面链接的谷歌文档,比如从jwks_uri端点获取密钥,如他们的发现文档所示。该端点返回以下内容:

代码语言:javascript
运行
复制
{
 "keys": [
  {
   "kty": "RSA",
   "alg": "RS256",
   "use": "sig",
   "kid": "1771931eb0eb64eb97733e857685be153e079bb9",
   "n": "AMNFQMNJw/EVwrYsyPTnEHWkaPinPb4ngc/SqD701aisFhbU9/wWoKADeFtwfBcWl1qjzIqhPorQElB+2mtiqUh3Qtaazt1x5wA9XnJDe6kjtMGm9nNLMilSVNBilAE8GIdbciMycISfOfL0WRaJrqpNxewNEVZjuYiGzOWahiDP",
   "e": "AQAB"
  },
  {
   "kty": "RSA",
   "alg": "RS256",
   "use": "sig",
   "kid": "7b3bc600209875d3c42ae277a0d018d1d21986ec",
   "n": "AN2UvG5+hNEMIPIbnpPm+JQi6LFWXBPzg3Ltb3xkVmSTjVaCFWppw/ZYRBgpToGKZP9XJstlOE88SDUFSMZIkIqtLpnUqmZax2Zc2gjEB9PhmHSH3/tTmtZ1U0X6V+crqitZ2uc3NV78vCn9/s+WuPwk/gfKBG8Cirb0fgLmsPd9",
   "e": "AQAB"
  }
 ]
}

查看JWT类的来源decodeverify方法,似乎$keys参数可以是一个数组,但是他们希望数组键是kid,数组值是:@param string|resource $key for HS*, a string key works. for RS*, must be a resource of an openssl public key。提取kid属性并将其用作数组键非常简单,但是应该使用什么作为数组值呢?

从谷歌的JWK文档来看,我们似乎在使用RS*,但我不知道关键对象的哪一部分是resource of an openssl public key。我尝试使用整个stdClass对象,只使用n字符串,但都在openssl_verify步骤中失败。该函数发出一个通知:“警告: openssl_verify():提供的密钥param不能强制进入公钥”。

所以,很明显,我传递的是错误的键,但是正确的键是什么呢?

为此,谷歌图书馆似乎使用不同端点来获取密钥。该端点似乎返回了一个证书数组。我需要用这样的东西代替吗?如果是这样,为什么文档会告诉您使用jwks_uri端点?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-02 00:08:53

两个端点包含相同的信息,但格式不同。

jwks_uri端点给出了RSA公钥的指数值。您可以使用这两个值来生成在https://www.googleapis.com/oauth2/v1/certs获得的PEM文件。

票数 6
EN

Stack Overflow用户

发布于 2015-01-16 13:13:21

对于那些将来尝试这样做的人,我想给出一个完整的答案;

ne部分在jwks_uri JSON密钥中给出了模数和指数,可以用来检索公钥(验证签名所需的全部内容)。本文详细介绍了在纯PHP中是如何做到这一点的:

openssl:如何从模数中获取公钥?

--但是,您应该知道,谷歌jwks_uri提供的JSON文档使用的是base64安全编码(即,替换+和/字符的普通base64 )。如果没有考虑到这一点,可能仍然会给出一个无效的证书。由于您提到使用php-jwt,从模数中获取公钥的工作代码和使用phpseclib的指数是:

代码语言:javascript
运行
复制
$modulus = 'someencodedmodulusvalue';
$exponent = 'someencodedexponentvalue'; 
$rsa = new Crypt_RSA();

$modulus = new Math_BigInteger(JWT::urlsafeB64Decode($modulus), 256);
$exponent = new Math_BigInteger(JWT::urlsafeB64Decode($exponent), 256);

$rsa->loadKey(array('n' => $modulus, 'e' => $exponent));
$rsa->setPublicKey();
$pubKey = $rsa->getPublicKey();
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25086410

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档