Skip to content
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

Signing/Verifying an ES256 JWT fails #64

Closed
dtarnawsky opened this issue Jan 25, 2024 · 3 comments
Closed

Signing/Verifying an ES256 JWT fails #64

dtarnawsky opened this issue Jan 25, 2024 · 3 comments

Comments

@dtarnawsky
Copy link

Using jwt.sign to create a JWT to post to Apple's Device Check API (docs) is resulting in an error "Missing or badly formatted authorization token". Apple's API requires an ES256 algorithm, private key and kid in the header.

I think there may a problem when signing with this algorithm so I wrote a unit test to sign and then verify the signed token which fails with an error InvalidAccessError: Unable to use this key to verify.

Here's the unit test to use:

import { describe, expect, test } from '@jest/globals'
import jwt from '../src/index'

describe('Test ES256 Sign and Verify', () => {
    test('ES256 Sign and Verify', async () => {        
        const secret = '-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgevZzL1gdAFr88hb2\nOF/2NxApJCzGCEDdfSp6VQO30hyhRANCAAQRWz+jn65BtOMvdyHKcvjBeBSDZH2r\n1RTwjmYSi9R/zpBnuQ4EiMnCqfMPWiZqB4QdbAd0E7oH50VpuZ1P087G\n-----END PRIVATE KEY-----';
        const token = await jwt.sign({
            iss: '123456789',
            iat: Math.floor(Date.now() / 1000) - (1 * 360),
            exp: Math.floor(Date.now() / 1000) + (24 * (60 * 60))
        }, secret, { algorithm: 'ES256', header: { kid: '987654321', type: 'JWT' } });

        const verified = await jwt.verify(token, secret, { algorithm: 'ES256', throwError: true })
        expect(verified).toBeTruthy()

    })
})

Perhaps I've written a bad unit test or Apple just doesn't like my token, but I figured it would be worth posting here to see if it looks like a real issue as I would think calling sign to get a token and then verifying it would result in a verified token.

@dtarnawsky
Copy link
Author

For anyone looking at this issue I found the answer using jose, the secret needs to be imported using importPKCS8.

There is likely an equivalent way with cloudflare-worker-jwt.

@zer0stars
Copy link

Having the same issue, do you have an example?

@dtarnawsky
Copy link
Author

Hey @zer0stars , if you are using the Device Check api from Apple then Apple will return this error when you are testing your app via XCode, if you deploy to Test Flight then it works - there is nothing wrong with the JWT and "Missing or badly formatted authorization token" really means that Apple will not accept it as it is coming from a device it does not trust. I ended up writing about this in this tutorial.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants