3 Replies
      Latest reply on Sep 11, 2019 5:15 PM by jaguth
      sudarshan.barigela Level 1 Level 1 (0 points)

        We're trying to generate and validate the authorization token for device check api , but getting the following error. Please check and update us with a solution.


        Error : "Unable to verify authorization token"

        Status Code : 401


        We've written the following code . Please verify and update if any changes need to be made.



        import java.io.BufferedReader;

        import java.io.File;

        import java.io.FileReader;

        import java.io.IOException;

        import java.security.KeyFactory;

        import java.security.NoSuchAlgorithmException;

        import java.security.PrivateKey;

        import java.security.spec.InvalidKeySpecException;

        import java.security.spec.PKCS8EncodedKeySpec;

        import java.util.Date;


        import org.bouncycastle.asn1.cms.TimeStampAndCRL;


        import com.nimbusds.jose.JWSAlgorithm;

        import com.nimbusds.jose.JWSHeader;

        import com.nimbusds.jose.JWSSigner;

        import com.nimbusds.jose.crypto.ECDSASigner;

        import com.nimbusds.jwt.JWTClaimsSet;

        import com.nimbusds.jwt.SignedJWT;

        import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;


        public class JWTUtil {



          public static void main(String[] args) {




          public static void generateJWTForiOS() {

          try {

          String kid = "-------"; // Can be found at: https://developer.apple.com/account/ios/authkey/

          String teamId = "-------"; // Can be found at: https://developer.apple.com/account/#/membership/

          PrivateKey key = loadIOSPrivateKey();

          Long timestamp = new Date().getTime();

          JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().build();

          JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.ES256).keyID(kid).customParam("iat", timestamp).customParam("iss", teamId).build();

          SignedJWT signedJWT = new SignedJWT(header, claimsSet);

          JWSSigner signer = new ECDSASigner((java.security.interfaces.ECPrivateKey) key);


          String token = signedJWT.serialize();


          } catch (Exception e) {





          public static PrivateKey loadIOSPrivateKey() {


          PrivateKey privateKey = null;


          try {


          File file = new File("..\\AuthKey_XXXXXXXX.p8");


          BufferedReader br = new BufferedReader(new FileReader(file));


          String st;

          StringBuilder strBuilder = new StringBuilder();

          while ((st = br.readLine()) != null){




          String privateKeyPEM = strBuilder.toString();

          privateKeyPEM = privateKeyPEM.replace("-----BEGIN PRIVATE KEY-----", "")

          .replace("-----END PRIVATE KEY-----", "").replaceAll("\\s", "");


          byte[] keyBytes = java.util.Base64.getDecoder().decode(privateKeyPEM);

          KeyFactory keyFactory = KeyFactory.getInstance("EC");

          privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));


          } catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {




          return privateKey;




        • Re: Unable to verify authorization token
          rroyo Level 1 Level 1 (0 points)



          Did you figure out how to create the JWT token to send to apple api? If so, can you please post a working sample code? I'm also facing the same issue, while implementing the device check api.

          • Re: Unable to verify authorization token
            skuehn Level 1 Level 1 (0 points)

            Use seconds instead of java Date milliseconds or use Date objects directly. And write complete JWSHeader and JWTClaimSet.


            String inputKeyFile = readAppleKeyFile();
            inputKeyFile = inputKeyFile.replaceFirst("-----BEGIN PRIVATE KEY-----", "");
            inputKeyFile = inputKeyFile.replaceFirst("-----END PRIVATE KEY-----", "");
            inputKeyFile = inputKeyFile.replaceAll("\\s", "");
            String clientSecret = "";
            try {
              final byte[] keyBytes = java.util.Base64.getDecoder().decode(inputKeyFile);
              final KeyFactory keyFactory = KeyFactory.getInstance("EC");
              final PrivateKey privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
              final Date timestamp = new Date();
              final Date exp = new Date(timestamp.getTime() + ttlMs);
              // see https://developer.apple.com/documentation/signinwithapplerestapi/generate_and_validate_tokens
              final JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.ES256)
              final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
              SignedJWT signedJWT = new SignedJWT(header, claimsSet);
              JWSSigner signer = new ECDSASigner((java.security.interfaces.ECPrivateKey) privateKey);
              String token = signedJWT.serialize();
              clientSecret = token;
            } catch (Exception e) {