Skip to content

Commit 2ace4e6

Browse files
authored
Merge pull request #692 from FroMage/webauthn4j
Added WebAuthn4J module
2 parents 4428e48 + 31154c6 commit 2ace4e6

35 files changed

+4746
-5
lines changed

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
<module>vertx-auth-htdigest</module>
3737
<module>vertx-auth-htpasswd</module>
3838
<module>vertx-auth-webauthn</module>
39+
<module>vertx-auth-webauthn4j</module>
3940
<module>vertx-auth-properties</module>
4041
<module>vertx-auth-sql-client</module>
4142
<module>vertx-auth-otp</module>

vertx-auth-common/src/main/java/module-info.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@
3434
io.vertx.ext.auth.impl.hash.SHA512,
3535
io.vertx.ext.auth.impl.hash.PBKDF2;
3636

37-
exports io.vertx.ext.auth.impl to io.vertx.auth.htdigest, io.vertx.auth.htpasswd, io.vertx.auth.oauth2, io.vertx.auth.otp, io.vertx.auth.sqlclient, io.vertx.auth.webauthn;
38-
exports io.vertx.ext.auth.impl.jose to io.vertx.auth.jwt, io.vertx.auth.oauth2, io.vertx.auth.webauthn, io.vertx.tests;
39-
exports io.vertx.ext.auth.impl.cose to io.vertx.auth.webauthn, io.vertx.tests;
40-
exports io.vertx.ext.auth.impl.asn to io.vertx.auth.webauthn;
37+
exports io.vertx.ext.auth.impl to io.vertx.auth.htdigest, io.vertx.auth.htpasswd, io.vertx.auth.oauth2, io.vertx.auth.otp, io.vertx.auth.sqlclient, io.vertx.auth.webauthn, io.vertx.auth.webauthn4j;
38+
exports io.vertx.ext.auth.impl.jose to io.vertx.auth.jwt, io.vertx.auth.oauth2, io.vertx.auth.webauthn, io.vertx.auth.webauthn4j, io.vertx.tests;
39+
exports io.vertx.ext.auth.impl.cose to io.vertx.auth.webauthn, io.vertx.auth.webauthn4j, io.vertx.tests;
40+
exports io.vertx.ext.auth.impl.asn to io.vertx.auth.webauthn, io.vertx.auth.webauthn4j;
4141
exports io.vertx.ext.auth.authorization.impl to io.vertx.auth.abac;
42-
exports io.vertx.ext.auth.impl.http to io.vertx.auth.oauth2, io.vertx.auth.webauthn;
42+
exports io.vertx.ext.auth.impl.http to io.vertx.auth.oauth2, io.vertx.auth.webauthn, io.vertx.auth.webauthn4j;
4343

4444
}

vertx-auth-webauthn4j/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/vertx-auth-webauthn/
2+
/.apt_generated_tests/

vertx-auth-webauthn4j/README.adoc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
= Vert.x WebAuthN4J Auth
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+
FIDO2 is a "passwordless" authentication mechanism and the JavaScript API is more known as WebAuthN.
7+
8+
WebAuthN allows users to authenticate using a secure device or token and no passwords are exchange between the browser and the server (also known as Relay Party).
9+
10+
The current implementation supports both authentication and device attestation.
11+
12+
Device attestation is a verification of the device itself.
13+
Currently the following attestations are implemented:
14+
15+
* none
16+
* U2F (FIDO-U2F tokens, e.g.: Yubikey's)
17+
* Packed
18+
* Android Key
19+
* Android Safetynet
20+
* TPM
21+
* Apple
22+
23+

vertx-auth-webauthn4j/pom.xml

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright 2014 Red Hat, Inc.
4+
~
5+
~ All rights reserved. This program and the accompanying materials
6+
~ are made available under the terms of the Eclipse Public License v1.0
7+
~ and Apache License v2.0 which accompanies this distribution.
8+
~
9+
~ The Eclipse Public License is available at
10+
~ http://www.eclipse.org/legal/epl-v10.html
11+
~
12+
~ The Apache License v2.0 is available at
13+
~ http://www.opensource.org/licenses/apache2.0.php
14+
~
15+
~ You may elect to redistribute this code under either of these licenses.
16+
-->
17+
18+
<project xmlns="https://maven.apache.org/POM/4.0.0"
19+
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
20+
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
21+
<parent>
22+
<artifactId>vertx-auth-parent</artifactId>
23+
<groupId>io.vertx</groupId>
24+
<version>5.0.0-SNAPSHOT</version>
25+
</parent>
26+
<modelVersion>4.0.0</modelVersion>
27+
28+
<artifactId>vertx-auth-webauthn4j</artifactId>
29+
30+
<properties>
31+
<doc.skip>false</doc.skip>
32+
<webauthn4j.version>0.27.0.RELEASE</webauthn4j.version>
33+
</properties>
34+
35+
36+
<dependencies>
37+
<dependency>
38+
<groupId>io.vertx</groupId>
39+
<artifactId>vertx-auth-common</artifactId>
40+
</dependency>
41+
<dependency>
42+
<groupId>com.webauthn4j</groupId>
43+
<artifactId>webauthn4j-core-async</artifactId>
44+
<version>${webauthn4j.version}</version>
45+
</dependency>
46+
<dependency>
47+
<groupId>com.webauthn4j</groupId>
48+
<artifactId>webauthn4j-metadata-async</artifactId>
49+
<version>${webauthn4j.version}</version>
50+
</dependency>
51+
<dependency>
52+
<groupId>com.webauthn4j</groupId>
53+
<artifactId>webauthn4j-test</artifactId>
54+
<scope>test</scope>
55+
<version>${webauthn4j.version}</version>
56+
<exclusions>
57+
<!--Causes double module import by different paths otherwise-->
58+
<exclusion>
59+
<groupId>org.springframework</groupId>
60+
<artifactId>spring-jcl</artifactId>
61+
</exclusion>
62+
</exclusions>
63+
</dependency>
64+
<dependency>
65+
<groupId>io.vertx</groupId>
66+
<artifactId>vertx-unit</artifactId>
67+
<scope>test</scope>
68+
</dependency>
69+
</dependencies>
70+
71+
<build>
72+
<plugins>
73+
<plugin>
74+
<groupId>org.codehaus.mojo</groupId>
75+
<artifactId>build-helper-maven-plugin</artifactId>
76+
<executions>
77+
<execution>
78+
<goals>
79+
<goal>attach-artifact</goal>
80+
</goals>
81+
<configuration>
82+
<artifacts>
83+
<artifact>
84+
<file>${basedir}/src/main/js/vertx-auth-webauthn4j.js</file>
85+
<classifier>client</classifier>
86+
<type>js</type>
87+
</artifact>
88+
</artifacts>
89+
</configuration>
90+
</execution>
91+
</executions>
92+
</plugin>
93+
</plugins>
94+
</build>
95+
96+
<profiles>
97+
<profile>
98+
<id>IT</id>
99+
<activation>
100+
<property>
101+
<name>env.CI</name>
102+
<value>true</value>
103+
</property>
104+
</activation>
105+
<build>
106+
<plugins>
107+
<plugin>
108+
<groupId>org.apache.maven.plugins</groupId>
109+
<artifactId>maven-failsafe-plugin</artifactId>
110+
<version>3.0.0</version>
111+
<executions>
112+
<execution>
113+
<goals>
114+
<goal>integration-test</goal>
115+
<goal>verify</goal>
116+
</goals>
117+
<configuration>
118+
<useModulePath>false</useModulePath>
119+
</configuration>
120+
</execution>
121+
</executions>
122+
</plugin>
123+
</plugins>
124+
</build>
125+
</profile>
126+
</profiles>
127+
128+
</project>
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
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

Comments
 (0)