Closed edwinius closed 10 months ago
Hello @edwinius, sorry for the delay. I wrote a quick script to confirm your issue:
const {
verifyAuthenticationResponse,
verifyRegistrationResponse
} = require('@simplewebauthn/server');
const {
decodeAttestationObject,
parseAuthenticatorData,
isoBase64URL,
} = require('@simplewebauthn/server/helpers');
const iOSRegResponse = {
id: 'FOTjVppiM_OvbuiwG4iZBRq0hsg',
rawId: 'FOTjVppiM_OvbuiwG4iZBRq0hsg',
response: {
attestationObject:
'o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViY7XiWdYBFaxUTCwPV3yKCwKoVd7sM9REl2ZnaTvsBZZFdAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBTk41aaYjPzr27osBuImQUatIbIpQECAyYgASFYIA7tS16_DCWmpc7DjOt3k_RGVQHl5gmDKf8e92mdShX8IlggBSq_P0ql6TiQAjSOR5hNtOJdRyHl9uwCtUlmssaYIEs',
clientDataJSON:
'eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwib3JpZ2luIjoiaHR0cDpcL1wvZGV2LmhhdmVud2FsbGV0LmlvIiwiY2hhbGxlbmdlIjoiQXFyMUk4UGdPa012ekdiZE82alBsd0NlX19aemhkV243MUtfeDNUZGdVMCJ9',
authenticatorAttachment: 'platform',
},
type: 'public-key',
clientExtensionResults: {},
};
const iOSAuthResponse = {
id: 'FOTjVppiM_OvbuiwG4iZBRq0hsg',
clientExtensionResults: {},
response: {
userHandle: 'NDkxNGFjY2YtMzFmYy00ZjBmLTlmYTktMDhlZTgxYWU4MDE2',
clientDataJSON:
'eyJvcmlnaW4iOiJodHRwOlwvXC9kZXYuaGF2ZW53YWxsZXQuaW8iLCJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiSlNJVnJ2QjVObG1keWNUWkhRZ2puMDdSUnlvOHBGY1VvOHNsRDdQYy1tVSJ9',
signature:
'MEYCIQDS7IZCmvyBwORAAllz1mUsjgHQONxuzvhUl1h-ot1IfAIhAKvN_wlDJt0gpqSfBdbFsqR88tSXviY2jlMLFiquLnP7',
authenticatorData: '7XiWdYBFaxUTCwPV3yKCwKoVd7sM9REl2ZnaTvsBZZEdAAAAAA',
},
rawId: 'FOTjVppiM_OvbuiwG4iZBRq0hsg',
authenticatorAttachment: 'platform',
type: 'public-key',
};
(async () => {
/**
* Registration
*/
const regVerification = await verifyRegistrationResponse({
expectedChallenge: 'Aqr1I8PgOkMvzGbdO6jPlwCe__ZzhdWn71K_x3TdgU0',
expectedOrigin: 'http://dev.havenwallet.io',
response: iOSRegResponse,
});
console.log('reg verified:', regVerification.verified); // true
/**
* Authentication
*/
// Pull values out of registration
const attestationObjectBuffer = isoBase64URL.toBuffer(iOSRegResponse.response.attestationObject);
const decodedAttestationObject = decodeAttestationObject(attestationObjectBuffer);
const authData = decodedAttestationObject.get('authData');
const parsedAuthData = parseAuthenticatorData(authData);
const authVerification = await verifyAuthenticationResponse({
expectedChallenge: 'JSIVrvB5NlmdycTZHQgjn07RRyo8pFcUo8slD7Pc-mU',
expectedOrigin: 'http://dev.havenwallet.io',
expectedRPID: 'dev.havenwallet.io',
response: iOSAuthResponse,
authenticator: {
counter: 0,
credentialID: parsedAuthData.credentialID,
credentialPublicKey: parsedAuthData.credentialPublicKey,
},
});
console.log('auth verified:', authVerification.verified); // false
})();
Everything works fine using browser and Android device. However from native iOS device, even though successfully registered passkey, couldn't get it to authorize the user.
At this point the fact that nothing about the response raises any other errors, and the signature at the very end can't be verified, and the fact that Android native APIs are fine with the same server-side verification logic, then I'm suspecting this is an iOS issue.
What specific version of iOS 16 are you running? I'm asking around my network to see if anyone else has experienced this before and might have a clue as to what's the culprit.
I'd also recommend updating to the latest iOS 17 if you can and see if the issue's been fixed.
Describe the issue
We are trying to implement passkey with our native iOS code using Swift which we have followed from the official Apple Developer https://developer.apple.com/documentation/authenticationservices/public-private_key_authentication/supporting_passkeys/ . However it seems that we always get invalid passkey even though the body seems alright.
Reproduction Steps
Using Swift native ASAuthorization
Expected behavior
Code Samples + WebAuthn Options and Responses
Here is the registrationData:
And this is the authenticate user data:
rawId and everything seems fine, but still always get invalid passkey
Dependencies
Everything works fine using browser and Android device. However from native iOS device, even though successfully registered passkey, couldn't get it to authorize the user.