Skip to content

One time password (OTP) support

Joshua Thijssen edited this page Apr 28, 2021 · 3 revisions

BitMaelum supports OneTimePassword / single sign-on systems. This means you can easily log into any site without registering first with simply your BitMaelum address, and a one time password generated from your mail client.

Prerequisites

Before a website can offer BitMaelum OTP, it must generate a keypair and expose the public key. This key is used for exchanging secrets between the BitMaelum client generating the OTP and the website. The key itself is exposed through DNS as a TXT record called _bitmaelum. This allows any client to easily fetch the public key from the website.

Secondly, the website must have a library for actually validating the OTP password. Currently, the following libraries are available:

Logging in from a user perspective:

  • User enters their bitmaelum address in the login field.
  • The user will open their bitmaelum client, and generates a new OTP password. The dialog will ask for which mail address and for which website.
  • The client will return an 8 digit password that is only valid for the given address/website combination AND only for 30 seconds.

Generating with the current bm-client application:

 bm-client otp --account <youraddress!> --site <website URL>

Technical

The client will fetch the site's public key through DNS. Together with the users private key, it will be used to key-exchange a shared secret. This secret will form the basis for an OTP code that will take into account the current time in 30 seconds intervals. This means that every 30 seconds the OTP code will change. Since you can (should) use a public key per site, OTP codes for an account will be different per site.

Generating the OTP code is done by fetching the current time interval (current time rounded to the lower 30 seconds interval). This time block is fed in an HMAC/sha256, together with the shared secret. This results in a 20-byte sha256 digest.

From this 20-byte hash, it will generate a 32-bit number:

  • it will take the first byte and mask with 0xF to fetch a number between 0 and 15
  • it will take this number as the offset in the 20-byte hash to fetch the 4 bytes that will make up the 32-bit number.
  • the MSB will be set to 0 (in order to deal with negative numbers)
  • The number will be modulo 10^length, where length is normally 8. Resulting in a number between 0 and 99999999.

Things to figure out

Q: Is an OTP "safe" enough?

OTP is based on a Diffie-Hellman exchange between two EC keys. The ED25519 keys are converted to an X25519 key, suffixed with the canonical site URL, and hashed with SHA256. This will be the base of the OTP.

Q: Can we have multiple login forms (with multiple public keys) on a single site?

In theory, we can, but it would mean a client must iterate ALL DNS entries.

Q: Doesn't the "_bitmaelum" key not collide with the regular DNS validation for organizations?

I think we are now using the _otp key instead. (needs verification)

Clone this wiki locally