|
| 1 | += WebAuthn4J auth provider |
| 2 | + |
| 3 | +This component contains a WebAuthn authentication mechanism using https://github.com/webauthn4j/webauthn4j[WebAuthn4J]. |
| 4 | +To use this project, add the following dependency to the _dependencies_ section of your build descriptor: |
| 5 | + |
| 6 | +* Maven (in your `pom.xml`): |
| 7 | +
|
| 8 | +[source,xml,subs="+attributes"] |
| 9 | +---- |
| 10 | +<dependency> |
| 11 | + <groupId>io.vertx</groupId> |
| 12 | + <artifactId>vertx-auth-webauthn4j</artifactId> |
| 13 | + <version>${maven.version}</version> |
| 14 | +</dependency> |
| 15 | +---- |
| 16 | + |
| 17 | +* Gradle (in your `build.gradle` file): |
| 18 | +
|
| 19 | +[source,groovy,subs="+attributes"] |
| 20 | +---- |
| 21 | +compile 'io.vertx:vertx-auth-webauthn4j:${maven.version}' |
| 22 | +---- |
| 23 | + |
| 24 | +https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API[WebAuthn (Web Authentication)] is a web standard for authenticating users to web-based applications using public/private key cryptography. |
| 25 | +Strictly speaking, WebAuthn is just the name of the browser API and is part of https://fidoalliance.org/fido2/[FIDO2]. |
| 26 | +FIDO2 is the overarching term of a set of specifications, including WebAuthn and CTAP. |
| 27 | +FIDO2 is the successor of the FIDO Universal 2nd Factor (U2F) legacy protocol. |
| 28 | + |
| 29 | +As an application developer, we don't deal with CTAP (Client-to-Authenticator Protocol), which is the protocol that the browser uses to speak with an authenticator like a FIDO security key. |
| 30 | + |
| 31 | +FIDO2 works with public/private keys. |
| 32 | +The user has an authenticator, which creates public/private key pairs. |
| 33 | +These key pairs are different for each site. |
| 34 | +The public key is transferred to the server and stored in the user's account. |
| 35 | +The private key never leaves the authenticator. |
| 36 | +To login, the server first creates a random challenge (a random sequence of bytes), sends it to the authenticator. |
| 37 | +The authenticator signs the challenge with his private key and sends the signature back to the server. |
| 38 | +The server verifies the signature with the stored public key and grants access if the signature is valid. |
| 39 | + |
| 40 | +Traditionally this technology needs a hardware security token like a https://www.yubico.com/products/[Yubico key] or a key from https://www.ftsafe.com/Products/FIDO[Feitian] to name two brands. |
| 41 | + |
| 42 | +FIDO2 still supports these hardware keys, but the technology also supports alternatives. |
| 43 | +If you have an Android 7+ phone or a Windows 10 system, you don't need to buy a FIDO2 security key if you want to play with WebAuthn. |
| 44 | + |
| 45 | +In https://fidoalliance.org/news-your-google-android-7-phone-is-now-a-fido2-security-key/[April 2019, Google announced] |
| 46 | +that any phone running Android 7+ can function as a FIDO2 security key. |
| 47 | +In |
| 48 | +https://www.microsoft.com/en-us/microsoft-365/blog/2018/11/20/sign-in-to-your-microsoft-account-without-a-password-using-windows-hello-or-a-security-key/[November 2018, Microsoft announced] |
| 49 | +that you can use Windows Hello as a security key for FIDO2. In https://developer.apple.com/videos/play/wwdc2020/10670/[June 2020 Apple announced] |
| 50 | +that you can use iOS FaceID and TouchID for the web by adopting webauthn standard. |
| 51 | + |
| 52 | +WebAuthn is implemented in Edge, Firefox, Chrome, and Safari. |
| 53 | +Visit https://caniuse.com to check out the current state of implementations: https://caniuse.com/#search=webauthn |
| 54 | + |
| 55 | +== WebAuthn4J API |
| 56 | + |
| 57 | +The https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API[Web Authentication API] is an extension of the https://developer.mozilla.org/en-US/docs/Web/API/Credential_Management_API[Credential Management API]. |
| 58 | + |
| 59 | +WebAuthn extends the two functions from the Credential Management API https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/create[navigator.credentials.create()] |
| 60 | +and https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get[navigator.credentials.get()] so they accept a publicKey parameter. |
| 61 | + |
| 62 | +To simplify the usage of the API a simple JavaScript client application is provided here: |
| 63 | + |
| 64 | +* Maven (in your `pom.xml`): |
| 65 | + |
| 66 | +[source,xml,subs="+attributes"] |
| 67 | +---- |
| 68 | +<dependency> |
| 69 | + <groupId>io.vertx</groupId> |
| 70 | + <artifactId>vertx-auth-webauthn4j</artifactId> |
| 71 | + <classifier>client</classifier> |
| 72 | + <type>js</type> |
| 73 | + <version>${maven.version}</version> |
| 74 | +</dependency> |
| 75 | +---- |
| 76 | + |
| 77 | +* Gradle (in your `build.gradle` file): |
| 78 | + |
| 79 | +[source,groovy,subs="+attributes"] |
| 80 | +---- |
| 81 | +compile 'io.vertx:vertx-auth-webauthn4j:${maven.version}:client@js' |
| 82 | +---- |
| 83 | + |
| 84 | +The script should be used in cooperation with vertx-web as it handles the API interaction between the web layer and the auth code in this library. |
| 85 | + |
| 86 | +== Registration |
| 87 | + |
| 88 | +Registration is the process of enrolling a new authenticator to the database and associate with the user. |
| 89 | + |
| 90 | +The process takes 2 steps: |
| 91 | + |
| 92 | +1. A call to generate a {@link io.vertx.ext.auth.webauthn4j.WebAuthn4J#createCredentialsOptions(JsonObject)} |
| 93 | +2. A call with the solution to the challenge to the normal `authenticate` API method. |
| 94 | + |
| 95 | +If the solution is correct, the new authenticator should be added to the storage and be usable for login purposes. |
| 96 | + |
| 97 | +== Login |
| 98 | + |
| 99 | +Like the registration, login is a 2 step process: |
| 100 | + |
| 101 | +1. A call to generate a {@link io.vertx.ext.auth.webauthn4j.WebAuthn4J#getCredentialsOptions(String)} |
| 102 | +2. A call with the solution to the challenge to the normal `authenticate` API method. |
| 103 | + |
| 104 | +When the challenge is correctly solved, the user is considered logged in. |
| 105 | + |
| 106 | +== Device Attestation |
| 107 | + |
| 108 | +When an authenticator registers a new key pair with a service, the authenticator signs the public key with an attestation certificate. |
| 109 | +The attestation certificate is built into the authenticator during manufacturing time and is specific to a device model. |
| 110 | +That is, all "Samsung Galaxy S8" phones, manufactured at a specific time or particular manufacturing run, have the same attestation certificate. |
| 111 | + |
| 112 | +Different devices have different attestation formats. |
| 113 | +The pre-defined attestation formats in WebAuthn are: |
| 114 | + |
| 115 | +* `Packed` - a generic attestation format that is commonly used by devices whose sole function is as a WebAuthn authenticator, such as security keys. |
| 116 | +* `TPM` - the Trusted Platform Module (TPM) is a set of specifications from the Trusted Platform Group (TPG). |
| 117 | +This attestation format is commonly found in desktop computers and is used by Windows Hello as its preferred attestation format. |
| 118 | +* `Android Key Attestation` - one of the features added in Android O was Android Key Attestation, which enables the Android operating system to attest to keys. |
| 119 | +* `Android SafetyNet` - prior to Android Key Attestation, the only option for Android devices was to create Android SafetyNet attestations |
| 120 | +* `FIDO U2F` - security keys that implement the FIDO U2F standard use this format |
| 121 | +* `Apple` - Verifies the Anonymous Apple device attestation. |
| 122 | +* `none` - browsers may prompt users whether they want a site to be allowed to see their attestation data and/or may remove attestation data from the authenticator's response if the `attestation` parameter in `navigator.credentials.create()` is set to `none` |
| 123 | + |
| 124 | +The purpose of attestation is to cryptographically prove that a newly generated key pair came from a specific device. |
| 125 | +This provides a root of trust for a newly generated key pair as well as being able to identify the attributes of a device being used (how the private key is protected; if / what kind of biometric is being used; whether a device has been certified; etc.). |
| 126 | + |
| 127 | +It should be noted that while attestation provides the capability for a root of trust, validating the root of trust is frequently not necessary. |
| 128 | +When registering an authenticator for a new account, typically a Trust On First Use (TOFU) model applies; and when adding an authenticator to an existing account, a user has already been authenticated and has established a secure session. |
| 129 | + |
| 130 | +== A simple example |
| 131 | + |
| 132 | +=== Create a Registration request |
| 133 | + |
| 134 | +[source,$lang] |
| 135 | +---- |
| 136 | +{@link examples.WebAuthN4JExamples#example1} |
| 137 | +---- |
| 138 | + |
| 139 | +=== Verify the registration request |
| 140 | + |
| 141 | +[source,$lang] |
| 142 | +---- |
| 143 | +{@link examples.WebAuthN4JExamples#example2} |
| 144 | +---- |
| 145 | + |
| 146 | +=== Create a Login request |
| 147 | + |
| 148 | +[source,$lang] |
| 149 | +---- |
| 150 | +{@link examples.WebAuthN4JExamples#example3} |
| 151 | +---- |
| 152 | + |
| 153 | +=== Verify the Login request |
| 154 | + |
| 155 | +[source,$lang] |
| 156 | +---- |
| 157 | +{@link examples.WebAuthN4JExamples#example4} |
| 158 | +---- |
| 159 | + |
| 160 | +== Metadata Service |
| 161 | + |
| 162 | +You can use the FIDO3 Metadata service by enabling the corresponding option, which means you **can** detect tokens |
| 163 | +that have been marked as not trustable by the token vendor. |
| 164 | +For example, when a security bug allowed a private key to be extracted from a token. |
| 165 | + |
| 166 | +Simply configure the application as: |
| 167 | + |
| 168 | +[source,$lang] |
| 169 | +---- |
| 170 | +{@link examples.WebAuthN4JExamples#example5} |
| 171 | +---- |
| 172 | + |
| 173 | +== Updating Certificates |
| 174 | + |
| 175 | +Almost all device attestations are based on `X509` Certificate checks. |
| 176 | +This means that certificates can and will expire at some point in time. |
| 177 | +By default, the current "Active" certificates are hardcoded on the `WebAuthn4JOptions` object. |
| 178 | + |
| 179 | +However if your application needs to update a certificate on it's own, say for example, use a more up to date one, or another with a different cypher, then you can replace the default `root` certificates for each attestation by calling: |
| 180 | +`WebAuthn4JOptions.putRootCertificate(String, String)`, where the first parameter is the attestation name or "mds" for FIDO MetaData Service: |
| 181 | + |
| 182 | +* none |
| 183 | +* u2f |
| 184 | +* packed |
| 185 | +* android-key |
| 186 | +* android-safetynet |
| 187 | +* tpm |
| 188 | +* apple |
| 189 | +* mds |
| 190 | + |
| 191 | +And the second the PEM formatted X509 Certificate (Boundaries are not required). |
| 192 | + |
| 193 | +[source,$lang] |
| 194 | +---- |
| 195 | +{@link examples.WebAuthN4JExamples#example6} |
| 196 | +---- |
0 commit comments