Skip to content

General Usage for Counter Based Token

Connie edited this page Jan 20, 2017 · 4 revisions

◄ Back (General Usage for Time-Based Token)

####General Usage for Counter-Based Token

var speakeasy = require("speakeasy");

Generating a key

// Generate a secret key.
var secret = speakeasy.generateSecret({length: 20});
// secret key is 20 characters long
// Access using secret.ascii, secret.hex, or secret.base32.

Getting a counter-based token for the current time

Calculating a counter-based token

// Get a counter-based token
var token = speakeasy.hotp({
  secret: secret.base32,
  encoding: 'base32',
  counter: 123
});

Verifying a counter-based token

var tokenValidates = speakeasy.hotp.verify({
  secret: secret.base32,
  encoding: 'base32',
  token: '123456',
  counter: 123
});

Using other encodings

The default encoding (when encoding is not specified) is ascii.

// Specifying an ASCII token for HOTP
// (encoding is 'ascii' by default)
var token = speakeasy.hotp({
  secret: secret.ascii,
  counter: 123456
});
// Specifying a hex token for HOTP
var token = speakeasy.hotp({
  secret: secret.hex,
  encoding: 'hex',
  counter: 123456
});

Using other hash algorithms

The default hash algorithm is SHA1.

// Specifying SHA256
var token = speakeasy.hotp({
  secret: secret.ascii,
  algorithm: 'sha256',
  counter: 123456
});
// Specifying SHA512
var token = speakeasy.hotp({
  secret: secret.ascii,
  algorithm: 'sha512',
  counter: 123456
});

Getting an otpauth:// URL and QR code for non-SHA1 hash algorithms

// Generate a secret, if needed
var secret = speakeasy.generateSecret({otpauth_url: false});
// By default, generateSecret() cannot generate an hotp otpauth_url.  
// Need to use otpauthURL to generate the url explicitely

// Use otpauthURL() to get a custom authentication URL for SHA512 and counter
var url = speakeasy.otpauthURL({ secret: secret.ascii, label: 'Name of Secret',
  algorithm: 'sha512', type: 'hotp', counter: 123456 });
// otpauth://hotp/Name%20of%20Secret?secret=<secret>&counter=123456&algorithm=SHA512

// Use otpauthURL() to get a custom authentication URL for base32, SHA512,
// issuer, counter and 6 digits
var url = speakeasy.otpauthURL({ secret: secret.base32, label: 'Name of Secret',
  algorithm: 'sha512', issuer:'Company', digits: 6, type: 'hotp', end
  counter: 123456, encoding: 'base32' });
// otpauth://hotp/Name%20of%20Secret?secret=<secret>&issuer=Company&counter=123456&algorithm=SHA512&digits=6

// Pass URL into a QR code generator

Specifying a window for verifying HOTP

Verify a HOTP token with counter value 42 and a window of 10. HOTP has a one-sided window, so this will check counter values from 42 to 52, inclusive, and return a { delta: n } where n is the difference between the given counter value and the counter position at which the token was found, or undefined if it was not found within the window. See the hotp․verifyDelta(options) documentation for more info.

var token = speakeasy.hotp.verifyDelta({
  secret: secret.ascii,
  counter: 42,
  token: '123456',
  window: 10
});

How this works:

// Set ASCII secret
var secret = 'rNONHRni6BAk7y2TiKrv';

// Get HOTP counter token at counter = 42
var counter42 = speakeasy.hotp({ secret: secret, counter: 42 });
// => '566646'

// Get HOTP counter token at counter = 45
var counter45 = speakeasy.hotp({ secret: secret, counter: 45 });
// => '323238'

// Verify the secret at counter 42 with the actual value and a window of 10
// This will check all counter values from 42 to 52, inclusive
speakeasy.hotp.verifyDelta({ secret: secret, counter: 42,
  token: counter42, window: 10 });
// => { delta: 0 } because the given token at counter 42 is 0 steps away from
// the given counter 42

// Verify the secret at counter 45, but give a counter of 42 and a window of 10
// This will check all counter values from 42 to 52, inclusive
speakeasy.hotp.verifyDelta({ secret: secret, counter: 42,
  token: counter45, window: 10 });
// => { delta: 3 } because the given token at counter 45 is 0 steps away from
// given counter 42

// Not in window: specify a window of 1, which only tests counters 42 and 43,
// not 45
speakeasy.hotp.verifyDelta({ secret: secret, counter: 42,
  token: counter45, window: 1 });
// => undefined

// Shortcut to use verify() to simply return whether it is verified as within
// the window
speakeasy.hotp.verify({ secret: secret, counter: 42,
  token: counter45, window: 10 });
// => true

// Not in window: specify a window of 1, which only tests counters 42 and 43,
// not 45
speakeasy.hotp.verify({ secret: secret, counter: 42,
  token: counter45, window: 1 });
// => false

As shown previously, you can also change verifyDelta() to verify() to simply return a boolean if the given token is within the given window.