The FIDO U2F protocol enables relying parties to offer a strong cryptographic 2nd factor option for end user security. The relying party’s dependence on passwords is reduced. The password can even be simplified to a 4-digit PIN or fingerprint sensor. End users carry a single U2F device which works with any relying party supporting the protocol. The user gets the convenience of a single ‘keychain’ device and convenient security
Done (During GSoC):
- Server - PR #5773 & commit #da8366e
- Added utility lib and fido2 helpers.
- Added Authenticator Keys (u2f, packed).
- Added Challenge generation for Registration & Login.
- Added Functions for parsing and authenticating keys.
- Added raw database to store in memory.
- Added server side routes.
- Added supporting unit tests in mocha and sinon.
- Added Missing “none” fmt keys support for BLE and NFC authentication.
- Client - PR #6033 & commit #9e81f9e
- Added client side utility file to parse and generate registration and login.
- Added client side model in backbone.js.
- Added view and templates in mustache.
- Added Client side routes.
To Do (Plan post GSoC):
- Add more tests for code coverage.
- Add TypeScript support.
- Redesign UI.
- Add future docs.
The Utility Helpers
Let’s store our utility helpers.
Create a file
cborand import those libraries in
const crypto = require('crypto'); const cbor = require('cbor');
The U2F device has a physical ‘test of user presence’. The user touches a button (sensor of some kind) to ‘activate’ the U2F device. It ensures that the relying party can trust in that the authentication process is actively triggered by the user himself.
- Let’s name this
U2F_REGISTERand export it.
/** * U2F PRESENCE CONSTANT */ exports.U2F_REGISTER = 0x01;
0x01 is the hexadecimal code which means 1 (i.e successful).
- Let’s define our
hashingfunction. A hash is a way to encrypt data into a fixed-length digest. This digest serves as a signature representing the original data that hashed. The various types of hashing algorithms are available in Node.js through the crypto module. This core module provides the wrappers on OpenSSL functions.
$ openssl list -digest-algorithms
Each algorithms has pros and cons and can be used according to need of application.
We will use
sha256for this application.
Following steps for creating hash:
cryptomodule (which we already did!)
Hashobject from crypto. For creating the hash object, you need to provide the algorithm to be used, mostly following three are used md5, sha1, sha256.
// const hash = crypto.createHash([algorithm-to-be-used]) const hash = crypto.createHash('sha256');
Set data to be hashed. We need to set data to be hashed to which we have to generate hash. This can be string, file object, along with data we need to specify the encoding type for data, this usually utf-8 or can be binary, ascii. If data is a Buffer then encoding-type is ignored.
// hash.update([data to be hashed], [encoding-type] ) hash_update = hash.update('Mozilla', 'utf-8');
Create the hash digest in required format. This digest takes parameter which asks for in which format the hash to be generated, this can be hex. If no encoding is provided, then a buffer is returned.
// generated_hash= hash_update.digest([format]) generated_hash = hash_update.digest('hex');
Let’s combine everything, more utility helpers are located in the fxa repository
I would like to thank my mentor Vijay Budhram and Firefox Accounts Team for helping and guiding me in the project throughout the gsoc journey!
I am thankful to Google Summer Of Code for providing me an opportunity to work with Mozilla.