{"id":19740764,"url":"https://github.com/duo-labs/android-webauthn-authenticator","last_synced_at":"2025-04-30T05:33:35.009Z","repository":{"id":56503191,"uuid":"168600830","full_name":"duo-labs/android-webauthn-authenticator","owner":"duo-labs","description":"A WebAuthn Authenticator for Android leveraging hardware-backed key storage and biometric user verification.","archived":false,"fork":false,"pushed_at":"2021-12-17T21:43:25.000Z","size":123,"stargazers_count":115,"open_issues_count":5,"forks_count":21,"subscribers_count":27,"default_branch":"master","last_synced_at":"2025-04-05T23:11:20.691Z","etag":null,"topics":["android","android-library","android-security","fido2","webauthn","webauthn-library"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/duo-labs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-31T21:36:41.000Z","updated_at":"2025-03-31T06:57:26.000Z","dependencies_parsed_at":"2022-08-15T20:00:33.189Z","dependency_job_id":null,"html_url":"https://github.com/duo-labs/android-webauthn-authenticator","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duo-labs%2Fandroid-webauthn-authenticator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duo-labs%2Fandroid-webauthn-authenticator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duo-labs%2Fandroid-webauthn-authenticator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duo-labs%2Fandroid-webauthn-authenticator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/duo-labs","download_url":"https://codeload.github.com/duo-labs/android-webauthn-authenticator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251650229,"owners_count":21621670,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-library","android-security","fido2","webauthn","webauthn-library"],"created_at":"2024-11-12T01:23:24.529Z","updated_at":"2025-04-30T05:33:34.666Z","avatar_url":"https://github.com/duo-labs.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Android WebAuthn Authenticator Library\n\nThis library is meant to serve as an example implementation of the [WebAuthn\nauthenticator model](https://www.w3.org/TR/webauthn/#sctn-authenticator-model).\nWhile the specification is currently in Candidate Recommendation, this library\nconforms as much as possible to the guidelines and implementation procedures\noutlined by the document.\n\nThis implementation currently requires Android API level 28 (Android 9.0) due\nto the use of the \n[BiometricPrompt](https://developer.android.com/reference/android/hardware/biometrics/BiometricPrompt).\n\n## Quickstart\n\nYou can use [JitPack](https://jitpack.io/) to include this module in your Android project, or you can include the source code.\n\n### Using JitPack\n\nAdd this in your root build.gradle:\n\n```groovy\n    allprojects {\n        repositories {\n            ...\n            maven { url 'https://jitpack.io' }\n        }\n    }\n```\nAdd this to your dependencies list:\n\n```groovy\n    dependencies {\n        implementation 'com.github.duo-labs:android-webauthn-authenticator:master-SNAPSHOT'\n    }\n```\n\n### Using Source\n\n#### Pull the source\n\n```\n$ cd ~/your/project/src/directory\n$ git clone git@github.com:duo-labs/android-webauthn-authenticator.git\n```\n\n#### Add the module to your Android project\n\nIn Android Studio: `File -\u003e New -\u003e Import Module` and then point it at the `android-webauthn-authenticator` directory.\n\n#### Add the module as a dependency\n\nIn Android Studio: `File -\u003e Project Structure -\u003e App -\u003e Dependencies -\u003e + -\u003e Module Dependency`\n\nSelect the `android-webauthn-authenticator` module. After a Gradle sync, you should be able to use the\n`duo.labs.webauthn` package.\n\n## Usage\n\nYou must first instantiate an `Authenticator` object.\n\n```java\n// Authenticator(Context ctx, boolean authenticationRequired, boolean strongboxRequired)\nAuthenticator authenticator = new Authenticator(context, true, true);\n```\nThe `Authenticator` object is safe to instantiate multiple times.\n\nThe arguments passed to the constructor determine whether the keys it generates will\nrequire biometric  authentication (i.e. can be turned off for testing) and if keys should\nbe stored by the [StrongBox Keymaster](https://developer.android.com/training/articles/keystore).\n\nNote that StrongBox is only available on some Android devices.\n\n### Make Credential (User Registration)\n\nYou can create a new credential by passing an `AuthenticatorMakeCredentialOptions` object to\n`Authenticator.makeCredential()`. You can instantiate an `AuthenticatorMakeCredentialOptions`\nobject directly and manually set its fields, or use our JSON format.\n\nOur JSON format mostly tracks the arguments to [authenticatorMakeCredential](https://www.w3.org/TR/webauthn/#op-make-cred)\nfrom the WebAuthn specification, with a few changes necessary for the serialization of binary data. Here's an example:\n\n```javascript\n{\n    \"authenticatorExtensions\": \"\", // optional and currently ignored\n    \"clientDataHash\": \"LTCT/hWLtJenIgi0oUhkJz7dE8ng+pej+i6YI1QQu60=\", // base64\n    \"credTypesAndPubKeyAlgs\": [\n        [\"public-key\", -7]\n    ],\n    \"excludeCredentials\": [\n        {\n            \"type\": \"public-key\",\n            \"id\": \"lVGyXHwz6vdYignKyctbkIkJto/ADbYbHhE7+ss/87o=\" // base64\n            // \"transports\" member optional but ignored\n        }\n    ],\n    \"requireResidentKey\": true,\n    \"requireUserPresence\": false,\n    \"requireUserVerification\": true,\n    \"rp\": {\n        \"name\": \"webauthn.io\",\n        \"id\": \"webauthn.io\"\n    },\n    \"user\": {\n        \"name\": \"testuser\",\n        \"displayName\": \"Test User\",\n        \"id\": \"/QIAAAAAAAAAAA==\" // base64\n    }\n}\n```\n\nNote that `requireResidentKey` and `requireUserPresence` are effectively ignored: keys are resident by design, and user presence will always be verified. User verification will always be performed if the `Authenticator` is instantiated with `authenticationRequired` set to `true`; otherwise biometric authentication will not be performed and credential generation will fail if `requireUserVerification` is `true`.\n\n(Per the spec, `requireUserPresence` must be the inverse of `requireUserVerification`)\n\nCreate the options object from JSON:\n\n```java\nAuthenticatorMakeCredentialOptions makeCredentialOptions = AuthenticatorMakeCredentialOptions.fromJSON(options);\n```\n\nThen, make a new credential with the options given.\n\n```java\nAttestationObject attestationObject = authenticator.makeCredential(makeCredentialOptions);\n// or if you want to require user verification and need the biometric dialog:\nAttestationObject attestationObject = authenticator.makeCredential(makeCredentialOptions, context, cancellationSignal);\n```\n\n`makeCredential` requires an application context in order to show the \n[BiometricPrompt](https://developer.android.com/reference/android/hardware/biometrics/BiometricPrompt), and\nalso accepts an optional [CancellationSignal](https://developer.android.com/reference/android/os/CancellationSignal)\nto allow user-initiated cancellation.\n\nOnce you have an `AttestationObject`, you can also retrieve its CBOR representation as follows:\n\n```java\nbyte[] attestationObjectBytes = attestationObject.asCBOR();\n```\n\n### Get Assertion (User Login)\n\nSimilar to `makeCredential`, `getAssertion` takes an `AuthenticatorGetAssertionOptions` object\nwhich you can either instantiate manually or deserialize from JSON.\n\nThe JSON format follows [authenticatorGetAssertion](https://www.w3.org/TR/webauthn/#op-get-assertion) with\nsome changes made for handling of binary data. Here's an example:\n\n```javascript\n{\n    \"allowCredentialDescriptorList\": [{\n        \"id\": \"jVtTOKLHRMN17I66w48XWuJadCitXg0xZKaZvHdtW6RDCJhxO6Cfff9qbYnZiMQ1pl8CzPkXcXEHwpQYFknN2w==\", // base64\n        \"type\": \"public-key\"\n    }],\n    \"authenticatorExtensions\": \"\", // optional and ignored\n    \"clientDataHash\": \"BWlg/oAqeIhMHkGAo10C3sf4U/sy0IohfKB0OlcfHHU=\", // base64\n    \"requireUserPresence\": true,\n    \"requireUserVerification\": false,\n    \"rpId\": \"webauthn.io\"\n}\n```\n\nCreate the options object from JSON:\n\n```java\nAuthenticatorGetAssertionOptions getAssertionOptions = AuthenticatorGetAssertionOptions.fromJSON(options);\n```\n\nStep 7 of [authenticatorGetAssertion](https://www.w3.org/TR/webauthn/#op-get-assertion) requires that\nthe authenticator prompt a credential selection. You can use our provided `SelectCredentialDialogFragment`\nto provide an interface for user-selection, or implement the `CredentialSelector` interface to receive a\ncallback when it is time to select a credential.\n\n#### Programmatic Credential Selection\n\nIf you want to programatically select credentials, you'll need to implement `CredentialSelector`, which is a simple interface:\n\n```java\npublic interface CredentialSelector {\n    public PublicKeyCredentialSource selectFrom(List\u003cPublicKeyCredentialSource\u003e credentialList);\n}\n```\n\nHere's a barebones example:\n\n```java\nAuthenticatorGetAssertionResult assertionObject = authenticator.getAssertion(getAssertionOptions, new CredentialSelector() {\n    @Override\n    public PublicKeyCredentialSource selectFrom(List\u003cPublicKeyCredentialSource\u003e credentialList) {\n        return credentialList.get(0);\n    }\n});\n```\n\n#### User-driven Credential Selection\n\nYou can also create a credential selector dialog by using the `SelectCredentialDialogFragment`\nhelper class, which takes a [DialogFragment](https://developer.android.com/reference/android/app/DialogFragment):\n\n```java\nSelectCredentialDialogFragment credentialSelector = new SelectCredentialDialogFragment();\ncredentialSelector.populateFragmentActivity(fragmentActivity);\nAuthenticatorGetAssertionResult assertionObject = authenticator.getAssertion(options, credentialSelector, context, cancellationSignal);\n```\n\nThe `fragmentActivity` supplied should be the main \n[Activity](https://developer.android.com/reference/android/app/Activity) \nwith which the user is currently interacting.\n\nAs with the `makeCredential` operation, in the user-driven case, `getAssertion` requires an application context in order to show the \n[BiometricPrompt](https://developer.android.com/reference/android/hardware/biometrics/BiometricPrompt)\nand accepts an optional \n[CancellationSignal](https://developer.android.com/reference/android/os/CancellationSignal)\nto allow user-initiated cancellation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduo-labs%2Fandroid-webauthn-authenticator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fduo-labs%2Fandroid-webauthn-authenticator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduo-labs%2Fandroid-webauthn-authenticator/lists"}