otplib
Time-based (TOTP) and HMAC-based (HOTP) One-Time Password library
About
otplib
is a JavaScript One Time Password (OTP) library.
It provides both functional and class based interfaces for
dealing with OTP generation and verification.
It implements both HOTP - RFC 4226 and TOTP - RFC 6238, and are tested against the test vectors provided in their respective RFC specifications. These datasets can be found in the packages/tests
folder.
This library is also compatible with Google Authenticator, and includes additional methods to allow you to work with Google Authenticator.
Demo and Documentation
Installation
Install the library via:
$ npm install otplib --save
$ npm install otplib@next --save
Release Type | Version |
---|
Current / Stable | |
Release Candidate | |
Upgrading
This library follows semver
. As such, major version bumps usually mean API changes or behavior changes. Please check upgrade notes for more information, especially before making any major upgrades.
You might also want to check out the release notes associated with each tagged versions in the releases page.
Getting Started
In node
import otplib from 'otplib';
const secret = otplib.authenticator.generateSecret();
const token = otplib.authenticator.generate(secret);
const isValid = otplib.authenticator.check(123456, secret);
const isValid = otplib.authenticator.verify({
secret,
token: 123456
});
Using specific OTP implementations
If you want to include a specific OTP specification, you can import it directly:
import hotp from 'otplib/hotp';
import totp from 'otplib/totp';
import authenticator from 'otplib/authenticator';
Note: If you import the libraries directly, you'll have to provide a crypto
solution (this is to allow custom crypto solutions), as long as they implement createHmac
and randomBytes
.
Take a look at the browser implementation
of this package as an example.
i.e.
import authenticator from 'otplib/authenticator';
import crypto from 'crypto';
authenticator.options = { crypto };
Using classes
For ease of use, the default exports are all instantiated instances of their respective classes.
You can access the original classes via it's same name property of the instantiated class.
i.e
import hotp from 'otplib/hotp';
const HOTP = hotp.HOTP;
import totp from 'otplib/totp';
const TOTP = totp.TOTP;
import authenticator from 'otplib/authenticator';
const Authenticator = authenticator.Authenticator;
Example Usage
import { Authenticator } from 'otplib/authenticator';
import crypto from 'crypto';
const authenticator = new Authenticator();
authenticator.options = {
secret: 'KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD',
algorithm: 'sha512',
step: 20,
digits: 8,
window: 1,
crypto
};
const token = authenticator.generate();
In browser
A browser-targeted version has been compiled.
You'll need to add the following scripts to your code:
<script src="otplib-browser.js"></script>
<script type="text/javascript">
</script>
You can find it in node_modules/otplib
after you install.
Alternatively you can
<script src="https://unpkg.com/otplib@^8.0.0/otplib-browser.js"></script>
For a live example, the project site has been built using otplib-browser.js
.
The source code can be found here.
Browser Compatibility
In order to reduce the size of the browser package, the crypto
package has been replaced with
an alternative implementation. The current implementation depends on Uint8Array
and the browser's native crypto methods, which may only be available in recent browser versions.
To find out more about the replacements, you can take a look at packages/otplib-browser/crypto.js
Output sizes:
- with node crypto: ~311Kb
- with alternative crypto: ~96Kb
Advanced Usage
Ihis library been split and classified into 6 core files with other specific environment based bundles provided.
Core
file | description |
---|
authenticator.js | Google Authenticator bindings |
core.js | Functions for various steps in the OTP generation process |
hotp.js | Wraps core functions into an instantiated HOTP class |
otplib.js | Library entry file, containing all instances with crypto set up |
totp.js | Wraps core functions into an instantiated TOTP class |
utils.js | Helper utilities |
Other Bundles
For more information about the functions, check out the documentation.
Notes
Setting Custom Options
All instantiated classes will have their options inherited from their respective options
generator. i.e. HOTP from hotpOptions
and TOTP/Authenticator from totpOptions
.
All OTP classes have an object setter and getter method to override these default options.
For example,
import otplib from 'otplib';
otplib.authenticator.options = {
step: 30,
window: 1
};
const opts = otplib.authenticator.options;
otplib.authenticator.resetOptions();
Available Options
Option | Type | Defaults | Description |
---|
algorithm | string | 'sha1' | Algorithm used for HMAC |
createHmacSecret | function | hotpSecret, totpSecret | Transforms the secret and applies any modifications like padding to it. |
crypto | object | node crypto | Crypto module to use. |
digits | integer | 6 | The length of the token |
encoding | string | 'ascii' ('hex' for Authenticator) | The encoding of secret which is given to digest |
epoch (totp) | integer | null | starting time since the UNIX epoch (seconds). Note non-javascript epoch. i.e. Date.now() / 1000 |
step (totp) | integer | 30 | Time step (seconds) |
window (totp) | integer or array | 0 | Tokens in the previous and future x-windows that should be considered valid. If integer, same value will be used for both. Alternatively, define array: [previous, future] |
Note 1: non "totp" label applies to all
Note 2: "totp" applies to authenticator as well
Seed / secret length
In RFC 6238, the secret / seed length for different algorithms is predefined:
HMAC-SHA1 - 20 bytes
HMAC-SHA256 - 32 bytes
HMAC-SHA512 - 64 bytes
As such, the length of the secret is padded and sliced according to the expected length for respective algrorithms.
Google Authenticator
Difference between Authenticator and TOTP
The default encoding option has been set to hex
(Authenticator) instead of ascii
(TOTP).
Base32 Keys and RFC3548
Google Authenticator requires keys to be base32 encoded.
It also requires the base32 encoder to be RFC 3548 compliant.
OTP calculation will still work should you want to use other base32 encoding methods (like Crockford's Base 32) but it will NOT be compatible with Google Authenticator.
import authenticator from 'otplib/authenticator';
const secret = authenticator.generateSecret();
const token = authenticator.generate(secret);
Displaying a QR code
You may want to generate and display a QR Code so that users can scan instead of manually entering the secret.
Google Authenticator and similar apps take in a QR code that holds a URL with the protocol otpauth://
,
which you get from otplib.authenticator.keyuri
.
While this library provides the "otpauth" uri, you'll need a library to generate the QR Code image.
An example is shown below:
import qrcode from 'qrcode';
import otplib from 'otplib';
const otpauth = otplib.authenticator.keyuri('user', 'service', secret);
qrcode.toDataURL(otpauth, (err, imageUrl) => {
if (err) {
console.log('Error with QR');
return;
}
console.log(imageUrl);
});
Contributing
Check out: CONTRIBUTING.md
License
otplib
is MIT licensed