https://developer.apple.com/documentation/signinwithapplerestapi/verifying_a_user
As per the above link, to verify an IDToken signature, Apple's public key needs to be used.
I am able to fetch Apple's public key, but I am unable to verify the signature of IDToken via the public key. I am trying to implement this in Java.. What exactly is meant by "JWS E256 signature"? Which algorithm?
Also, once public key is fetched (sample PK posted below), which algorithm to use to form the public key?
{
"keys": [
{
"kty": "RSA",
"kid": "AIDOPK1",
"use": "sig",
"alg": "RS256",
"n": "someValue",
"e": "someValue"
}
]
}
Basically, n is the RSA key modulus and e is exponent. They are both encoded with Base64 URL format. With them you create the RSA public key and use it with JWT library like JJWT to decode the JWT token. Here is a very basic example on Java:
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.*;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.KeySpec;
import java.security.spec.RSAPublicKeySpec;
private static PublicKey getPublicKey() throws Exception {
String publicKeyString = N;
String publicKeyExponent = E;
BigInteger n = new BigInteger(1, Decoders.BASE64URL.decode(publicKeyString));
BigInteger e = new BigInteger(1, Decoders.BASE64URL.decode(publicKeyExponent));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
KeySpec publicKeySpec = new RSAPublicKeySpec(n, e);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
return publicKey;
}
private static void decodeJwt(String jwt) throws Exception {
PublicKey publicKey = getPublicKey();
Jwts.parser()
.setSigningKey(publicKey)
.parseClaimsJws(jwt)
.getBody(); // will throw exception if token is expired, etc.
}