Tropical Stay v1.1.0 Release Notes -- Adding WebAuthn Support
What is WebAuthn?
WebAuthn is a new web standard that enables web applications to strongly authenticate their users using public key cryptography. Up until recently we used things we knew like usernames, passwords, and secret questions to authenticate ourselves, and then had to rely on the website we’re interacting with to protect this information. As we have seen in the news many, many times over the past few years, an alarming number of companies have failed to do this properly which has resulted in the compromise of their users' personal information. These breeches have caused millions and millions of people to have their sensitive personal data exposed and often sold for criminal purposes. See the Block.one blog post that tells a bit of that story.
WebAuthn is a significant upgrade in authentication technology and allows a more reliable, harder-to-hack form of authentication that could very well lead to “password-less login” for your favorite websites. To read what a password-less future would be like, see this Block.one article.
Here is a great non-technical introduction to the kind of password-less authentication WebAuthn enables.
A quick, mildly-technical video brief can be found here.
For a somewhat-detailed, but readable introduction, read this article from PCWorld.
For more in-depth, see this article from Yubico.
WebAuthn provides interactive strong authentication between two entities, typically an end user and a website or app provider, known as the Relying Party, without the Relying Party having to trust the client software -- browser, web page, mobile app, etc. The blockchain network cannot perform the role of Relying Party so WebAuthn can’t generally be used as a login for an EOSIO blockchain, but it can be used as primary or secondary authentication factor for a specific blockchain application communicating with a particular EOSIO-based blockchain.
Let’s look at two domains: public (systems that are transparent and in the cloud like most blockchains we are familiar with) and private (services provided by a private company or government services, where the websites and services are owned privately).
In the case of smart contract-based blockchains, individual apps written for those platforms could use WebAuthn to act as a second factor added on top of a traditional primary authentication, reducing the attack surface of the components typically involved in signing a transaction, eg. browser, signature provider, web connection. See below for more on this topic.
WebAuthn can also secure and simplify the login process for websites as well as private, web-serviced blockchain applications. Once the user has authenticated themselves they can enroll a key from a WebAuthn-enabled device, then use that enrolled device as a primary authentication replacing the need to log in with a password.
Mitigation of Common Web Security Issues
Web browsers are notoriously insecure. They have implemented strict policies that restrict what can happen in code in the browser’s context, but attack vectors continue to be hard to avoid in some cases.
WebAuthn allows for an end-to-end path of trust from server to authenticating device, reducing the potential of a malicious actor tampering with a transaction in the browser. WebAuthn also allows the authenticator function to be moved to an external physical device, eliminating one of the weaknesses in signing a transaction; namely that the software-based authenticators doing the signing have an attack surface a hacker can try to exploit. The attack surface of a WebAuthn-enabled device is far smaller than the attack surface of a software authenticator.
Now, when you return to the app, you’ll see that in the drop-down menu, you now have an
Enable WebAuthn 2FA option in the login drop-down menu. Click that to begin the WebAuthn ceremony. Behind the scenes, this ceremony is establishing a private key that will represent you to the Tropical Stay example app.
The Tropical example requests that your browser verify you. In this screenshot, you see Chrome asking the user which form of authentication they would like to use: the “USB security key”, a hardware authentication device, or the “Built-in sensor” which is the TouchID fingerprint reader on my Macbook Pro. I’ll select the fingerprint reader.
I touch my finger to the fingerprint reader.
Chrome then does a final check with the user to ensure I intend to share this important information with the browser. I click Allow to give Chrome access to the key that has been generated in the background for me. Chrome can now use this key to confirm with websites that it is actually me sitting in front of my computer and logging in or taking other action.
Click the Continue button to proceed to the Properties page.
On the Properties page, we now have the “Rent” button, which allows us to commit to renting a property. This is a high-risk activity when compared to Liking a property, so we will again verify the user’s identity via WebAuthn.
The transaction request will then pop up in Scatter and request you Allow the transaction to be signed.
How The Demo Works
NOTE: This is not a description of the WebAuthn standard itself. WebAuthn is acting as only part of the specialized use of the standard in the sample app as a second factor.
Both the server and the user have key pairs. The user’s is generated from some sort of specialized hardware made for this purpose, eg. a USB Security Key or other authentication device, and the server’s is a pre-generated key pair, like a server would use to sign/verify a JWT token. When a higher-risk action is taken by the user, the client and server communicate and each other and sign a challenge. That challenge can then be verified in a smart contract as having been provably signed by the server and a WebAuthn authenticator the server believes is associated with the user.
The Process -- Step 1: Enrolling a Device
First, the app enrolls a public key and Credential ID from a local hardware authentication device. This consists of the browser requesting a public key and the associated Credential ID from the authentication device and sending it to the server, where the user’s public key and Credential ID are stored. The client doesn’t need to store any state about the key pair the device generates. The Credential ID is what the authentication device uses to re-generate the appropriate key pair. It is stored by the server and passed to the client each time something is signed.
The Process - Step 2: Performing a Higher-Risk Action
When the user performs a higher-risk activity and they or the application wants that action protected by a second factor, the client requests a challenge from the server. The server returns a challenge that it has signed with its own private key, and which it generates from the public key it already knows to be associated with the user from the user’s enrollment process, and some concrete data associated with the higher-risk activity being undertaken.
Once a challenge has been received from the server, the client makes a new request of the authentication device to sign the challenge and wraps up that signed challenge in an authenticated transaction, a
rent transaction, as in the case of the Tropical Stay example. This transaction contains the
- Transaction details needed to execute the contract action
- User’s account name
- Property name
- WebAuthn challenge-related credentials
- server’s public key
- server’s signature (something only the server could generate -- very similar to how JWT tokens are used)
- User’s public key
- User’s signed challenge
Finally, the transaction is broadcast to the chain with the challenge-based credentials included in the transaction. The contract, then, can reconstruct the challenge the server generated, and verify the server’s signature and thus the user’s signature, based on the server’s public key which acts as a root in a chain of trust.. The signatures could only have been generated by the private keys, so verifying both signatures successfully proves that the two entities we expect to be involved in the transaction were, actually, the entities involved.
Running the Tropical Example App
This example app demonstrates a use case for using WebAuthn as a 2nd factor. Previously in the Tropical Stay example, we demonstrated the capacity to Like a property, which required a Signature Provider to sign a
like transaction. Liking is a relatively low-risk activity. However, what do you do when you have a higher-risk activity that, for example, includes money or a financial commitment?
In this extended Tropical Stay example, we add renting, which represents a user committing financially to rent a property. This is a much more weighty action than simply Liking a property.
For simplicity, in this article, we will refer to low-risk actions (like Liking) and higher-risk actions (like Renting).
eosio/contracts/tropical/, you'll find the contract code and abi.
The frontend code that interacts with the user and responds to the request to rent as well as the construction of the
rent action is found in
The bulk of the WebAuthn code is implemented as server code in this example. You can find that in
Running the example
First, you'll need an instance of the blockchain running locally. To launch that, pull the .deb image from
and put it in the repo's
Internally, grab the .deb file from the buildkite artifacts from any
EOSIO build (that's passing and is building the right branch). You'll find it in the 'Ubuntu 18.04 - Package Builder' build step (near the very end of the list).
yarn up and wait for the chain to start (you'll see block production begin).
Then launch the frontend. The example requires HTTPS for the WebAuthn stuff to work properly. So after you clone the repo, you'll run the following small modification of the typical startup…
yarn HTTPS=true yarn start
Under the Profile/Login drop-down menu, in addition to the Login that has been there, you'll now find an option for 2FA (once you're logged in). Click the Enable 2FA to start the WebAuthn ceremony. It'll walk you through step by step. You'll need to have your Mac's TouchID configured or an authentication device plugged in (and if you have both, you'll need to select one when the browser presents you with that option).
In the body of the example, you'll now see both a Like button, which will act as Liking acted before, as well as the new Rent button, which will make use of the WebAuthn key. When you click Rent, you'll need to verify yourself again (via your TouchID or authentication device), and then sign the transaction (via your Signature Provider, which could be Scatter, the Chrome Reference Authenticator, or other Signature Provider.)
Disclaimer: All repositories and other materials are provided subject to this IMPORTANT notice and you must familiarize yourself with its terms. The notice contains important information, limitations and restrictions relating to our software, publications, trademarks, third-party resources, and forward-looking statements. By accessing any of our repositories and other materials, you accept and agree to the terms of the notice.