yubikeyotp

Low-level Yubikey OTP decryption / verification library for node.js

yubikeyotp

Low-level Yubikey OTP decryption / verification library for node.js.

npm install yubikeyotp
var yubikeyotp = require('yubikeyotp');
 
// hex-encoded AES key 
var aeskey = 'e6cdae77f55ac1db4acd3b7fd8151334';
 
// modhex-encoded OTP key generated by Yubikey programmed with above key 
var otp = 'khdnrutkdendbrbghdjcidkhveuhbrcuublkdjfttcrk';
 
// result contents documented below 
var result = yubikeyotp.parseOTP(otp, aeskey);
 
console.log(result);

Output:

{ pubUid: '962bced923b2',
  uid: '4e8308389518',
  useCtr: 7,
  tstp: 1768874,
  sessionCtr: 0,
  rnd: 199,
  crc: 50219 }
var yubikeyotp = require('yubikeyotp');
 
yubikeyotp.verifyOTP({
    otp: 'ccccccdbrrebjrtefjjcklkuehfjrktcfikdidujblvv',
    id: 'xxxxx', // replace with real ID 
    key: 'xxxxx', // replace with real key 
    sl: '100',
    timestamp: true
}, function(errresults) {
    console.log(results);
});

Output:

{ h: 'XpqsKMYH3DVXOGXHZeXqyKmdMVs',
  t: '2014-02-14T19:26:41Z0233',
  otp: 'ccccccbfttfbuldcefjvnkeijhljrhdcjerhccundbjd',
  nonce: 'szUJ2dCI7gEPinJfKvu0fAIFoEi8DU',
  sl: '100',
  timestamp: '5993928',
  sessioncounter: '338',
  sessionuse: '0',
  status: 'OK' }

parseOTP decrypts OTP using given AES key and returns false when the OTP is malformed or computed CRC16 does not match. Otherwise object with following properties is returned:

  • pubUid: hex-encoded public UID (it is part of OTP string)
  • uid: hex-encoded private UID (programmed on key along with AES key)
  • useCtr: 15-bit boot counter - number of times Yubikey device was booted (inserted into USB port) since last reconfiguration
  • tstp: 24-bit timer counting at approximately 8 Hz since last device boot (initialized randomly at boot)
  • sessionCtr: 8-bit usage counter since last boot (bumps useCtr when overflowing)
  • rnd: 16-bit random number
  • crc: 16-bit CRC checksum (already verified by parseOTP method)

This method works offline and is synchronous.

verifyOTP takes OTP along with Yubikey API id and optional API key and verifies using Yubicloud Web API. Arguments:

  • options object with following properties:
    • otp: required - modhex-encoded OTP to verify, generated with Yubikey
    • id: required - your API id
    • key: optional - your base64 encoded API key - if provided it will be used to sign request. This allows verification of server response.
    • nonce: optional - defaults to random string generated by crypto.pseudoRandomBytes. Nonce used in request.
    • apiUrl: optional - API endpoint URL - defaults to https://api.yubico.com/wsapi/2.0/verify. Can be changed to use private cloud.
    • requestParams: optional - defaults to {}. Can be used to override request parameters (e.g. proxy settings).
    • timestamp: optional - boolean defaults to false. If set to true, requests timestamp and session counter information to be added to response.
    • sl: optional - defaults to false. Can be value 0 to 100 indicating percentage of syncing required by client, or strings "fast" or "secure" to use server-configured values; if absent, let the server decide (as per protocol spec).
    • timeout: optional - defaults to false. Number of seconds server will wait for sync responses; if absent, let the server decide (as per protocol spec).
  • callback takes function with parameters err and result. err contains error string or null if server responded with well-formed and properly signed answer. In this case result is an object with following properties (unmodified as received from server):
    • otp: original OTP from request (automatically verified by method)
    • nonce: nonce from request
    • h: HMAC-SHA1 signature (automatically verified by method)
    • t: string with UTC timestamp
    • timestamp: present if timestamp was requested. Contains internal Yubikey timestamp
    • sessioncounter: present if timestamp was requested. Contains interal Yubikey boot counter
    • sessionuse: present if timestamp was requested. Contains interal Yubikey session counter
    • sl: percentage of external validation server that replied successfully (0 to 100)
    • status: one of following (as per protocol spec):
      • OK: The OTP is valid.
      • BAD_OTP: The OTP is invalid format.
      • REPLAYED_OTP: The OTP has already been seen by the service.
      • BAD_SIGNATURE: The HMAC signature verification failed.
      • MISSING_PARAMETER: The request lacks a parameter.
      • NO_SUCH_CLIENT: The request id does not exist.
      • OPERATION_NOT_ALLOWED: The request id is not allowed to verify OTPs.
      • BACKEND_ERROR: Unexpected error on server.
      • NOT_ENOUGH_ANSWERS: Server could not get requested number of syncs during requested timeout
      • REPLAYED_REQUEST: Server has seen the OTP/Nonce combination before

This method requires internet connection and is asynchronous.