aws-samples / amazon-cognito-passwordless-auth

Passwordless authentication with Amazon Cognito: FIDO2 (WebAuthn, support for Passkeys), Magic Link, SMS OTP Step Up
Apache License 2.0
382 stars 70 forks source link

Workaround for Uint8Array JWK data #142

Closed rsquires closed 9 months ago

rsquires commented 9 months ago

At least in my testing, the FIDO2 authentication always seems to fail. Peeking at the Lambda logs, I found the following:

2024-01-26T18:34:44.657Z    ca4400f5-ba8c-4d22-96e6-8d54db827ff5    ERROR   TypeError [ERR_INVALID_ARG_TYPE]: The "key.n" property must be of type string. Received an instance of Uint8Array
    at new NodeError (node:internal/errors:405:5)
    at validateString (node:internal/validators:162:11)
    at getKeyObjectHandleFromJwk (node:internal/crypto/keys:497:3)
    at prepareAsymmetricKey (node:internal/crypto/keys:549:22)
    at createPublicKey (node:internal/crypto/keys:613:5)
    at verifyChallenge (file:///var/task/index.mjs:177:96)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async addChallengeVerificationResultToEvent (file:///var/task/index.mjs:113:5)
    at async Runtime.handler (file:///var/task/index.mjs:1717:7) {
  code: 'ERR_INVALID_ARG_TYPE'
}

With a little console.log() debugging, the type of storedCredential.jwk.n is Uint8Array.

2024-01-26T18:34:44.484Z    ca4400f5-ba8c-4d22-96e6-8d54db827ff5    INFO    {
  kty: 'RSA',
  alg: 'RS256',
  e: Uint8Array(3) [ 1, 0, 1 ],
  n: Uint8Array(256) [
    169, 184, 118,  29, 122, 170, 239, 120, 140, 155, 171,  56,
    209, 133,  30, 199, 212, 123,  33, 213,  96, 229, 131,  48,
     63, 178,  72, 223,  80, 151, 216,  37, 255,  85,  94,  25,
    254, 239, 193,  53, 208, 150, 178,   9, 221, 227, 137,   9,
     30,  30, 183,  94, 214,  68, 171,  54,  27, 221, 129, 135,
     39, 191,   1,  14,  34,  37,  50, 124, 129, 137, 136,  12,
    194, 126, 238, 211, 120,  94, 178, 113,  87, 184, 104, 187,
     45,  86, 195,  86,  66, 172,   2, 243, 113, 147,  80,  26,
     36,  35, 222,   3,
    ... 156 more items
  ]
}

Description of changes: This is more of hack, but ensuring the key data is a base64-encoded string seems to get everything back in order. I'm currently evaluating/prototyping with the amazon-cognito-passwordless-auth package, so I don't have enough time to find the true root cause, hence this being a draft PR. But, I still wanted to give you guys a heads up.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

ottokruse commented 9 months ago

Interesting! What type of Authenticator is that you're using?

ottokruse commented 9 months ago

Need to have a look in the spec what we should be expecting. Is this per spec or is the particular Authenticator a bit idiosyncratic 😅

rsquires commented 9 months ago

Hey, I was testing with Firefox on Windows 10 with the Windows Hello authenticator.

ottokruse commented 9 months ago

After a closer look I think we should add .toString("base64url") after n and e to these lines:

https://github.com/aws-samples/amazon-cognito-passwordless-auth/blob/04031a420c85a8852507d78d8d6e111ad9b54128/cdk/custom-auth/fido2-credentials-api.ts#L802-L808

Similar to how we do it for ES:

https://github.com/aws-samples/amazon-cognito-passwordless-auth/blob/04031a420c85a8852507d78d8d6e111ad9b54128/cdk/custom-auth/fido2-credentials-api.ts#L789-L796

ottokruse commented 9 months ago

Wanna do that in your PR?

ottokruse commented 9 months ago

Friendly nudge :)

ottokruse commented 9 months ago

Doing it in #148