We hear a lot about how passwords are insecure, and should not be used alone for authentication. They are hard to remember, so users are tempted to come up with weak passwords, and reuse them across multiple websites. Even if the password is strong, it’s still just a short string the users know.
There are numerous ways to mitigate this, such as HMAC or time-based one-time passwords or more recently universal 2nd-factor hardware tokens. They all based on something the user has, rather than something they know. What they have is a secret key, which they can use to generate a password or sign messages.
What seems to be forgotten in the consumer world is that every browser has had a feature built-in since TLS was introduced, called mutual authentication, which allows the user to present a certificate as well as the server. This means the user can authenticate with something they have and – if the certificate is protected by a passphrase – something they know.
In this post, we implement a simple Node.js example which uses client certificates to authenticate the user.