I am working in a restricted environment and don't have the ability to utilise any third party systems that would make this simple, such as Firebase/php-jwt
I have received a JWT I would like to verify. I have a JWK from which I need to reconstruct the public key, to complete the verification.
The JWK is as follows
{
"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"
}
The code I am using to generate the public key is as follows
$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);
This results in an error
openssl_verify(): supplied key param cannot be coerced into a public key
I feel like I'm missing something obvious and I am somehow generating the key incorrectly. I tried asking ChatGPT for help but it gave me many different solutions, all of which led back to the same error. Further reading has led me to some ideas similar to the AI suggestions, but again all led to the same error
These included:
- Trying various different whitespacing, from none at all, to chunking by 64 chars
- Encoding the modulus and exponent in different ways (I didn't understand these suggestions at all)
- Prepending the fixed string
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAto the modulus, this seems to be something to do with RSA keys, but I don't really understand what this is
I'm really not sure what else I can do here, this feels like it should be such a simple thing, but I'm just not getting it and I've run out of angles to approach
I thought it might just be a simple formatting issue some simple code could fix, so I wrote the following to try to produce a valid pem. The code runs with your JWT and the example pem shown without emitting the '...cannot be coerced into a public key' error. That doesn't mean it is correct. Anyway, you can play with this. It might be useful, or not.
Output