f-23 / react-native-passkey

Passkeys for React Native
MIT License
121 stars 25 forks source link

react-native-passkey with android #26

Closed Elolawyn closed 6 months ago

Elolawyn commented 6 months ago

Hi, I am executing a demo with this library using fido2-lib on the backend with mocked data. I have the assetlinks.json and the apple-app-site-association and the devide is aking me to generate or use passkey when i press the buttons that execute the methods this library is providing so everything seems to be working fine but I have one question regarding the origin this library provides in the result returned by the methods.

The registrationRequest the library is using, given by the fido2-lib's method attestationOptions contain the following information:

{
  rp: {
    name: 'My web',
    id: 'my-web.com'
  },
  user: {
    id: 'someId',
    name: 'User Name',
    displayName: 'Display User Name'
  },
  challenge: 'challenge_properly_formed',
  pubKeyCredParams: [
    { type: 'public-key', alg: -7 },
    { type: 'public-key', alg: -257 },
  ],
  timeout: 10000,
  attestation: 'direct',
  authenticatorSelection: {
    authenticatorAttachment: 'platform',
    requireResidentKey: true,
    userVerification: 'required'
  }
}

On iOS, the PasskeyRegistrationResult the library is returning provided me the following clientDataObj:

{
  type: 'webauthn.create',
  challenge: 'challenge_properly_formed',
  origin: 'https://my-web.com'
}

https://my-web.com is a backend serving the android and ios files properly.

apple-app-site-association

{
  webcredentials: {
    apps: ['value.com.org.package']
  }
}

assetlinks.json

[
  {
    relation: ['delegate_permission/common.handle_all_urls', 'delegate_permission/common.get_login_creds'],
    target: {
      namespace: 'android_app',
      package_name: 'com.org.package',
      sha256_cert_fingerprints: ['HEX_VALUE']
    }
  }
]

So when i compare this info against what my backend should have everything works fine. The fido2-lib method is working:

const expectedAttestationResult: ExpectedAttestationResult = {
  challenge: 'challenge_properly_formed',
  origin: 'https://my-web.com',
  factor: 'first'
}

const attestationResult: Fido2AttestationResult = await f2l.attestationResult(
  clientAttestationResult,
  expectedAttestationResult
)

However, on android, the library returns the following clientDataObj:

{
  type: 'webauthn.create',
  challenge: 'challenge_properly_formed',
  origin: 'android:apk-key-hash:HASH',
  androidPackageName: 'com.org.package'
}

The attestationResult method returns Error: clientData origin did not match expected origin.

I know this might be more on the fido2-lib side of things, and i will ask them too but, is the PasskeyRegistrationResult returned by the library on android the way it should be? Is the library getting the info about the origin from those files served by the backend?

f-23 commented 6 months ago

hi @Elolawyn

the result you receive from the RegistrationRequest on Android seems correct to me. Android uses the SHA-256 hash of the signing certificate used when building ur APK. You can read more about it here.

In your case you could add that android:apk-key-hash:HASH origin to the list of allowed origins in your backend, or pass info about the used platform (Android, iOS, Web) alongside the registration result when sending it to the server. Then just verify using the corresponding origin of the platform.

Elolawyn commented 6 months ago

Thanks for the answer.