Php 我应该将密钥对象的哪一部分传递到“openssl\u verify”以验证谷歌签名的JWT?

Php 我应该将密钥对象的哪一部分传递到“openssl\u verify”以验证谷歌签名的JWT?,php,single-sign-on,google-oauth,jwt,Php,Single Sign On,Google Oauth,Jwt,我试图用Google和OpenID Connect实现一个联邦登录系统,但我一直在验证和解析从Google获得的JWT id令牌。我跟在这里 根据文档的建议,我正在尝试使用现有的JWT库。GitHub上最流行的PHP版本似乎是。问题似乎出在JWK密钥的格式上 上面链接的谷歌文档表示,可以从发现文档中显示的jwks\u uri端点获取密钥。该端点返回以下内容: { "keys": [ { "kty": "RSA", "alg": "RS256", "use": "sig",

我试图用Google和OpenID Connect实现一个联邦登录系统,但我一直在验证和解析从Google获得的JWT id令牌。我跟在这里

根据文档的建议,我正在尝试使用现有的JWT库。GitHub上最流行的PHP版本似乎是。问题似乎出在JWK密钥的格式上

上面链接的谷歌文档表示,可以从发现文档中显示的
jwks\u uri
端点获取密钥。该端点返回以下内容:

{
 "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类的
decode
verify
方法,似乎
$keys
参数可以是一个数组,但他们希望数组键是
kid
,数组值是:
@param string | resource$key for HS*,字符串键可以工作。对于RS*,必须是openssl公钥的资源
。拉出
kid
属性并将它们用作数组键非常简单,但是应该使用什么作为数组值呢

从Google的JWKs文档中,看起来我们使用的是
RS*
,但我不知道密钥对象的哪个部分是openssl公钥的
资源。我尝试过使用整个stdClass对象和
n
字符串,但都失败了。该函数发出一条通知:“警告:openssl_verify():提供的密钥参数不能强制转换为公钥”

很明显,我输入了错误的键,但什么是正确的键


因为这似乎是用a来获得钥匙的。该端点似乎返回一个证书数组。我需要用这样的东西来代替吗?如果是这样,为什么文档会告诉您使用
jwks\u uri
端点?

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


jwks_uri
端点提供RSA公钥的指数值。您可以使用这两个值来生成获取的PEM文件

对于将来试图这样做的人,我想提供一个完整的答案

jwks_uri
JSON密钥中的
n
e
部分给出了模数和指数,可用于检索公钥(这是验证签名所需的全部内容)。这篇文章详细介绍了如何在纯PHP中实现这一点:

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


谢谢,我对密码学还是新手,所以我没有我需要的词汇。你会建议我切换端点还是使用不同的JWT库来处理
jwks_uri
端点提供的格式?好吧,我根本不是php专家,所以我不能推荐你应该使用的JWT库。然而,我发现这两个主题:和。如果您仍然想使用
jwks\u uri
端点并使用模数和指数值构建PEM,它们可以帮助您。再次感谢您的帮助。我发现了一个nice,它似乎支持模数和指数键格式,所以我认为改变它将是阻力最小的路径。
$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();