Host Origin Based Authentication (HOBA) Demo and Code!
Using the Demo
Use the login box on the right to log on and off the site, as well as join. Once you login/join you can logout. That's pretty much it. If you're expecting something more exciting, you are missing the point that not putting a secret onto a wire is pretty exciting.
You can create any number of new accounts and log into any of them at any time; just use logout to switch between them
Enrolling a new device happens when there is no key available for the current device, and you want to log into an existing account. What I usually do is have Chrome and Firefox open and Join in one of them, and then use the other browser to try to login too. Of course this works with say using your browser and your phone/tablet too.
If it says that it can't use HOBA, make sure you are using a https: url, and use either chrome or firefox
If you want to log in from a new device, just login as usual, and it will prompt you get an OTP to enroll that device in your email
This site does spectacularly little after logging in. This is a feature, not a bug
If you want to clear all of your local keys click Clear
How HOBA works
Login Flow Get the user name and fetch the key pair from the credential store. Generate the URL and sign the URL. Client sends the login request to login.php. Server verifies the signature and responds with an HTTP style response code
Initial Join Flow Get the user name and email. Generate a new key pair and store the key pair for this user. Generate the URL. Sign the URL and send to join.php. Server verifies the signature, and fails if it doesn't verify. Server then checks to see if user name is available, and if available creates a new user and stores the public key in a table of userid/publickey tuples. Server then responds with a HTTP style response code
Enroll New Device Flow Get the user name and find that it doesn't have a credential. Generate a new key pair and store it for the user. Generate the URL with the new public key to be enrolled. Sign the URL and send to login.php (from the user's standpoint they are just logging in). Server verifies the signature, and fails if it doesn't verify. Server emails an OTP to the user. User gets email and enters OTP on the client. Client then sends a new login request with the OTP and public key to login.php. Server verifies the signature and the OTP and stores the new public key in a table of userid/publickey tuples. Server then responds with a HTTP style response code
Logout has nothing to do with HOBA per se... it just kills off the session cookie as usual
Following Along in the Code
You can view the code here at hoba-bis repo if you want to follow along with what's going on with the demo
Most of the action wrt HOBA in the code is happening in hoba/js/loginbox.js for signing, the main hoba module is hoba/hobacmn.php which is used by login.php for verifying and enrolling new keys and join.php for signing up. The HOBA specific parts of loginbox.js are what would need to be integrated with your own login UI. The HOBA specific parts of login.php and join.php would need to be integrated with your user database and authentication backend
In this example email provides an out of band mechanism for the server to send an OTP to prove ownership of the account. SMS and other mechanisms can also be employed
Like most things, most of this is UI. Don't let that deter you. I've tried to point out the juicy bits to show what is actually new and different in the code.
This version of the demo has two different ways to prove freshess: a time+replay cache approach, and a nonce based approach patterened after RFC 7616. It's an open question of which is better, as always. I really don't have a dog in that fight, so you can choose.
If you complain that the backend is written in PHP, you will be obligated to write it in your own favorite language
If you can lift the Hoba you can win valuable prizes
TODO
This code doesn't support email verification for join, but it would work the same as password based enroll
I make an effort at dealing with edge cases, but this is a prototype so it's likely that I've missed some
There is currently no way to delete a user. Stale credentials just get rejected for no such user when logging in
The credentials between classic rsa stuff and webCrypto don't interoperate for some reason. Since this is just a demo, it's nbd
The credentials are stored in localStorage. It's ongoing concern about whether that's ok or not. However unsecured physical access to any device is highly problematic, so the main consideration is public/shared devices