-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Verifying/Decoding Apple's x5c JWT signatures #465
Comments
I figured it out with the excellent help provided on Stack Overflow. The first item in the x5c array is the certificate used to sign the JWT and that certificate holds the public key. The certs in the x5c array are DER certs, but openssl wants PEM certs when it does verification. As far as I can tell, converting a DER cert to a PEM cert just involves taking the DER data, base64 encoding it, limiting it to 64 characters wide per line, then wrapping it in
The php-jwt library will take an OpenSSLAsymmetricKey object as the key data, and openssl_pkey_get_public() will return that type of object. You can pass the PEM certificate string into that function and it'll parse and extract the public key:
|
Thank you! This helped me. |
So if I'm understanding this correctly, the To solve your issue generally in the library, we would be able to do something like make the second parameter optional, and if the Some things I don't understand
I imagine these questions could be answered with a bit more research on |
From the explanation of Auth0 - https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-set-properties:
So the first certificate should contain the key, any other certificates are part of the chain and are used to verify the first certificate. About the missing |
That's interesting - so is it recommended that all certificates in the chain are verified, or only the first one?
From ietf rfc:
|
May someone helps a class that also checks the other certificates. <?php
namespace helpers;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use stdClass;
class AppleJWSHelper {
private const CERTIFICATE_AUTHORITIE = 'https://www.apple.com/certificateauthority/AppleRootCA-G3.cer';
public static function decode(string $signedPayload): stdClass {
list($headerB64) = explode('.', $signedPayload);
$headerText = JWT::urlsafeB64Decode($headerB64);
$header = JWT::jsonDecode($headerText);
$intermediateCertificate = self::wrapCertificate($header->x5c[1]);
$rootCertificate = self::wrapCertificate($header->x5c[2]);
$certificateAuthority = self::getCertificateAuthority();
if (openssl_x509_verify($intermediateCertificate, $rootCertificate) === 1 && openssl_x509_verify($rootCertificate, $certificateAuthority) === 1) {
$certificate = self::wrapCertificate($header->x5c[0]);
$publicKey = openssl_pkey_get_public($certificate);
return JWT::decode($signedPayload, new Key($publicKey, $header->alg));
}
throw new \Exception('Payload could not be verified');
}
private static function wrapCertificate(string $certificateB64): string {
$wrappedCertificateText = trim(chunk_split($certificateB64, 64));
return <<<EOD
-----BEGIN CERTIFICATE-----
$wrappedCertificateText
-----END CERTIFICATE-----
EOD;
}
private static function getCertificateAuthority(): string {
//Only for testing, dont use in production
$cert = file_get_contents(self::CERTIFICATE_AUTHORITIE);
$cert = base64_encode($cert);
return self::wrapCertificate($cert);
}
}
|
@ItsReddi |
You should not download the authority on the fly. |
@ItsReddi Oh, I thought the method was unavailable, thanks. |
I tried using the auth keys published on Apple's website:
...but it horks with the following error:
I looked through the JWT::decode() method, and it's looking for a key id ("kid") in the header of the signed transaction JWT, but Apple doesn't provide a "kid" in the header of the signed transaction JWT. The structure of the header looks like this:
I'm an experienced developer in a hundred other topics, but this is my first time working with JWTs, so I'm doing my best to understand the various interacting pieces here.
How can I properly decode/verify the JWTs with x5c from Apple?
The text was updated successfully, but these errors were encountered: