I am trying to implement a federated login system with Google and OpenID Connect, and I delay checking and parsing the JWT identifier that I am returning from Google. I follow the google documentation here.
Accepting document recommendations, I am trying to use the existing JWT library. The most popular version of PHP on GitHub is PHP_JWT . The problem is the JWK key format.
The Google docs linked above are said to get the keys from the jwks_uri , as shown in their docs document. This endpoint returns the following:
{ "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" } ] } / SqD701aisFhbU9 / wWoKADeFtwfBcWl1qjzIqhPorQElB + 2mtiqUh3Qtaazt1x5wA9XnJDe6kjtMGm9nNLMilSVNBilAE8GIdbciMycISfOfL0WRaJrqpNxewNEVZjuYiGzOWahiDP", { "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" } ] } + JQi6LFWXBPzg3Ltb3xkVmSTjVaCFWppw / ZYRBgpToGKZP9XJstlOE88SDUFSMZIkIqtLpnUqmZax2Zc2gjEB9PhmHSH3 / tTmtZ1U0X6V + crqitZ2uc3NV78vCn9 / s + WuPwk / gfKBG8Cirb0fgLmsPd9", { "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" } ] }
Considering the source for the JWT decode and verify class methods, it seems that the $keys parameter can be an array, but they expect the array keys to be kid and the array values โโwill be like this: @param string|resource $key for HS*, a string key works. for RS*, must be a resource of an openssl public key @param string|resource $key for HS*, a string key works. for RS*, must be a resource of an openssl public key . It's simple enough to pull out kid properties and use them as array keys, but what should be used as array values?
From the Google JWK document, it seems we are using RS* , but I have no idea which part of the key object is the resource of an openssl public key . I tried using the whole stdClass object and only the string n , but both are executed with the openssl_verify step. This function issues a notification: "Warning: openssl_verify (): the specified key parameter cannot be forced into the public key."
So itโs obvious that I am going to the wrong key, but what is the correct key?
The Google library for this seems to use a different endpoint to get the keys. This endpoint seems to return an array of certificates. Do I need to use something like this? If so, why should documents indicate the jwks_uri ?