Dolphin
Dolphin

Reputation: 39015

how to parse jwt sign key from apple p8 file with Java

Now I want to generate an JWT token to request apple server follow this docs, I have the p8 file download from apple, how to get jwt sign key from p8 file? this is my jwt token generate code:

Map<String,Object> jwtHeader = new HashMap<>();
        jwtHeader.put("alg","ES256");
        jwtHeader.put("kid","YDKL424AF9");
        jwtHeader.put("typ","JWT");
        Map<String,Object> appleJwtPayload = new HashMap<>();
        appleJwtPayload.put("iss","5fb8e836-27d7-4390-8f40-008acd64a29d");
        appleJwtPayload.put("iat",System.currentTimeMillis() / 1000L);
        appleJwtPayload.put("exp",System.currentTimeMillis() / 1000L + 60 * 15);
        appleJwtPayload.put("aud","appstoreconnect-v1");
        appleJwtPayload.put("nonce",UUID.randomUUID().toString());
        appleJwtPayload.put("bid","com.earth.dolphin");
        String appleKey = "<how to get the apple key>";
        SecretKey secretKey = new SecretKeySpec(appleKey.getBytes(), SignatureAlgorithm.ES256.getJcaName());
        String accessToken = Jwts.builder()
                .setClaims(appleJwtPayload)
                .setHeader(jwtHeader)
                .signWith(secretKey)
                .compact();

I read the KeyStore code follow this question, but I still could not figure out how to do it, any one could help me?

Upvotes: 6

Views: 5913

Answers (1)

Dolphin
Dolphin

Reputation: 39015

get the sign key like this:

byte[] p8der = Files.readAllBytes(Path.of("/opt/apps/dolphin-post/AuthKey_YDKL424AF9.p8"));
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(new org.apache.commons.codec.binary.Base64().decode(p8der));
PrivateKey appleKey = KeyFactory.getInstance("EC").generatePrivate(priPKCS8);

the file AuthKey_YDKL424AF9.p8 was download from apple, you should remove the begin and end header of the file. This is my full function to get private key:

public static PrivateKey getPrivateKey(String filename, String algorithm) throws IOException {
        String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8");
        try {
            String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
                    .replace("-----END PRIVATE KEY-----", "")
                    .replaceAll("\\s+", "");

            KeyFactory kf = KeyFactory.getInstance(algorithm);
            return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Java did not support the algorithm:" + algorithm, e);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("Invalid key format");
        }
    }

you can use it like this:

PrivateKey appleKey = SecurityUtil.getPrivateKey(APPLE_PRIVATE_KEY_PATH,"EC");

the APPLE_PRIVATE_KEY_PATH in my OS is:

apple.private.key.path=/opt/apps/dolphin-post/AuthKey.p8

changed it to your path.

Upvotes: 9

Related Questions