为了验证一个google oauth2令牌,我将根据以下公式中的模数(n)和指数(e)为kid“b863b534069bfc0207197bcf831320d1cdc2cee2”生成一个公钥:
{
"alg": "RS256",
"n": "8h6tCwOYDPtzyFivNaIguQVc_yBO5eOA2kUu_MAN8s4VWn8tIfCbVvcAz3yNwQuGpkdNg8gTk9QmReXl4SE8m7aCa0iRcBBWLyPUt6TM1RkYE51rOGYhjWxo9V8ogMXSBclE6x0t8qFY00l5O34gjYzXtyvyBX7Sw5mGuNLVAzq2nsCTnIsHrIaBy70IKU3FLsJ_PRYyViXP1nfo9872q3mtn7bJ7_hqss0vDgUiNAqPztVIsrZinFbaTgXjLhBlUjFWgJx_g4p76CJkjQ3-puZRU5A0D04KvqQ_0AWcN1Q8pvwQ9V4uGHm6Bop9nUhIcZJYjjlTM9Pkx_JnVOfekw",
"use": "sig",
"kid": "b863b534069bfc0207197bcf831320d1cdc2cee2",
"e": "AQAB",
"kty": "RSA"
}
字符串
然后在php中创建RSA 256公钥:
$rsa = new Crypt_RSA();
$modulus = new Math_BigInteger(base64url_decode($cert["n"]), 256);
$exponent = new Math_BigInteger(base64url_decode($cert["e"]), 256);
$rsa->loadKey(array('n' => $modulus, 'e' => $exponent));
$rsa->setPublicKey();
$public_key = $rsa->getPublicKey();
型
这将生成公钥:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuopEuQyOKMsQq90I/5on
1nNBPc7stMvsN1HC+Pgyu8nJ1qWwaAAqIv4edo2oG/Bo3eg6p+OjG3nbFL62S6hE
aJLUVfxhW5GQuxQlsvaA2MsZuZCRyKTv8bm641wM+biGVZLiDsLRylVdpxf4aGa9
9zZw+QZMVKL4f9B4SunyTugTaCIu8LBOQesCQp/QJaUjqMDhfEvoFQXiCn6zo3rW
EWBiKxiFBizH9jSfWimJecFhn0Vlv/Vs7pRb0X2y66VS3gTvR6/A3ooNz3tYAJPM
GoE8fAiEghYXXHjmWmgdRx9Qt9sa/ACwv7yx0Th27fw+rrsMSrUyaqRpn/fjIMTu
sQIDAQAB
-----END PUBLIC KEY-----
型
同样的方法也适用于谷歌的其他几十个RS256 kid,但公钥不适用于这个特定的kid。
我正在验证签名:
openssl_verify($payload_to_verify, $safe_signature, $public_key, OPENSSL_ALGO_SHA256);
型
响应为“0”表示失败。
编辑#2:找到谷歌版本的公钥:
https://www.googleapis.com/oauth2/v1/certs的
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8h6tCwOYDPtzyFivNaIg
uQVc/yBO5eOA2kUu/MAN8s4VWn8tIfCbVvcAz3yNwQuGpkdNg8gTk9QmReXl4SE8
m7aCa0iRcBBWLyPUt6TM1RkYE51rOGYhjWxo9V8ogMXSBclE6x0t8qFY00l5O34g
jYzXtyvyBX7Sw5mGuNLVAzq2nsCTnIsHrIaBy70IKU3FLsJ/PRYyViXP1nfo9872
q3mtn7bJ7/hqss0vDgUiNAqPztVIsrZinFbaTgXjLhBlUjFWgJx/g4p76CJkjQ3+
puZRU5A0D04KvqQ/0AWcN1Q8pvwQ9V4uGHm6Bop9nUhIcZJYjjlTM9Pkx/JnVOfe
kwIDAQAB
-----END PUBLIC KEY-----
型
我生成的公钥不一样,为什么我生成的公钥是错的?
2条答案
按热度按时间esyap4oy1#
我确认RSA Crypt软件包未正确转换密钥。
我尝试用另一个应用程序(web-token/jwt-app)转换该密钥,得到的结果与Google提供的结果相同。
字符串
最好是警告phpseclib/phpseclib这个问题。
sulc1iza2#
我写了一个简单的
validate_id_token
函数:字符串
该函数验证由
参数:
$id_token -登录提供程序返回的令牌(
/#id_token=eyJ....
)$target_client_id -令牌生成器的客户端ID(您可以在开发人员帐户的令牌管理中获取)
$target_kid:
1.通过登录提供程序进行登录,以获取一些临时ID令牌(它将在
/#id_token=eyJ....
上返回)1.复制id令牌并在https://jwt.io/上输入
1.您的子值位于解码的HEADER x1c 0d1x下
$pubkey_pem
1.如果您使用的是Microsoft登录提供程序,请转到:https://login.microsoftonline.com/common/discovery/v2.0/keys如果您使用的是Google登录提供程序,请转到:https://www.googleapis.com/oauth2/v3/certs
1.在你访问的URL上,搜索kid值。在我的例子中,
1.复制带有kid值的Json对象(在
keys
下,您只需要复制带有匹配的kid值的json项,并将Json对象粘贴到https://keytool.online/上
1.选择PEM PKS#8选项卡
你有
$pubkey_pem
的值(-----BEGIN PUBLIC KEY-----
的东西)你需要将整个生成的文本复制到$pubkey_pem
中现在你已经有了函数的所有参数。获取
$pubkey_pem
、$target_kid
和$target_client_id
的过程是每个登录提供程序的一次过程。