我在受限环境中工作,无法利用任何第三方系统来简化此操作,例如 Firebase/php-jwt
我已收到我想要验证的 JWT。我有一个 JWK,我需要从中重建公钥,以完成验证。
JWK如下
{
"kty": "RSA",
"use": "enc",
"n": "ozmvkuGzWNHs9cEcC5PWwbG-dmSjPcoQFxEbqH_fBjkj_nfTTKshdiSq5ciulWEa_rrqQ2qwcSADNxtTzRR1qfud-NvsM8VltT7xDuVVqPTZoWLKa0BWXgQQ-1mCm1KdGltYWccB0R1LoF-rb3DEEZySsHvqErYzYt4M_rqjEiK5Y9y1h3k1h5Yk4zGLWchko3jiDS-pVevvWsQsN-Y3KuB19485G9P_MXLtfJWQ4wC4jlo9etdD_hgDfxX-hQy3wuwHfHifLdxvxiB8X5Is4m6DuY4_7hS5RwXAjO1QSd-zUYZNT_2yWVR56_jyiZEiOdgIm9QtLPZCTKzqsXoqZQ",
"e": "AQAB"
}
我用来生成公钥的代码如下
$jwk = json_decode($jwk);
$rsaPublicKey = "-----BEGIN PUBLIC KEY-----\n";
$rsaPublicKey .= "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA{$jwk->modulus}";
$rsaPublicKey .= "{$jwk->exponent}\n-----END PUBLIC KEY-----";
$isSignatureValid = openssl_verify($dataToVerify, $signature, $rsaPublicKey, OPENSSL_ALGO_SHA256);
这会导致错误
openssl_verify(): supplied key param cannot be coerced into a public key
我觉得我错过了一些明显的东西,并且我以某种方式错误地生成了密钥。我尝试向 ChatGPT 寻求帮助,但它给了我许多不同的解决方案,所有这些都导致了相同的错误。进一步的阅读让我想到了一些类似于人工智能建议的想法,但又都导致了同样的错误
其中包括:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
,这似乎与RSA密钥有关,但我不太明白这是什么我真的不知道我还能在这里做什么,这感觉应该是一件很简单的事情,但我只是不明白,而且我已经没有办法接近
我认为这可能只是一个简单的格式问题,一些简单的代码可以修复,所以我编写了以下内容来尝试生成有效的 pem。但使用您提供的 JWK 时,它不起作用。该代码使用显示的示例 pem 运行,不会发出“...无法强制转换为公钥”错误。您可能会注意到它生成的文本长度与示例不同。你确定JWK是正确的吗?无论如何,你可以玩这个。可能有用,也可能没用。
<?php
$json = array();
$json['kty'] = 'RSA';
$json['use'] = 'enc';
$json['n'] = 'ozmvkuGzWNHs9cEcC5PWwbG-dmSjPcoQFxEbqH_fBjkj_nfTTKshdiSq5ciulWEa_rrqQ2qwcSADNxtTzRR1qfud-NvsM8VltT7xDuVVqPTZoWLKa0BWXgQQ-1mCm1KdGltYWccB0R1LoF-rb3DEEZySsHvqErYzYt4M_rqjEiK5Y9y1h3k1h5Yk4zGLWchko3jiDS-pVevvWsQsN-Y3KuB19485G9P_MXLtfJWQ4wC4jlo9etdD_hgDfxX-hQy3wuwHfHifLdxvxiB8X5Is4m6DuY4_7hS5RwXAjO1QSd-zUYZNT_2yWVR56_jyiZEiOdgIm9QtLPZCTKzqsXoqZQ';
$json['e'] = 'AQAB';
$rsaPublicHeader = "-----BEGIN PUBLIC KEY-----\n";
$rsaPublicBody = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA".strtr($json['n'].$json['e'], '-_', '+/');
$rsaPublicFooter = "-----END PUBLIC KEY-----";
$pem = $rsaPublicHeader;
$k = 0;
$rsaPublicBodyLen = strlen($rsaPublicBody);
for ($i = 0; $i<$rsaPublicBodyLen; $i+=64) {
$pem .= substr($rsaPublicBody, $i, 64)."\n";
}
$pem .= $rsaPublicFooter;
$dataToVerify = "";
$signature = "";
/*
// Example pem taken from https://github.com/Strobotti/php-jwk
$pem = "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4dGQ7bQK8LgILOdLsYzf
ZjkEAoQeVC/aqyc8GC6RX7dq/KvRAQAWPvkam8VQv4GK5T4ogklEKEvj5ISBamdD
Nq1n52TpxQwI2EqxSk7I9fKPKhRt4F8+2yETlYvye+2s6NeWJim0KBtOVrk0gWvE
Dgd6WOqJl/yt5WBISvILNyVg1qAAM8JeX6dRPosahRVDjA52G2X+Tip84wqwyRpU
lq2ybzcLh3zyhCitBOebiRWDQfG26EH9lTlJhll+p/Dg8vAXxJLIJ4SNLcqgFeZe
4OfHLgdzMvxXZJnPp/VgmkcpUdRotazKZumj6dBPcXI/XID4Z4Z3OM1KrZPJNdUh
xwIDAQAB
-----END PUBLIC KEY-----";
*/
echo $pem."\n";
$isSignatureValid = openssl_verify($dataToVerify, $signature, $pem, OPENSSL_ALGO_SHA256);
if ($isSignatureValid) {
echo ("Valid\n");
} else {
echo ("Invalid\n");
}
?>