Search code examples
javascriptcryptojsmulti-factor-authenticationone-time-passwordpostman-pre-request-script

Generating an OTP in Postman via JavaScript


I am trying to generate and OTP via JavaScript within Postman. I am doing some automated testing and needs to use and OTP to meet MFA requirements. I have found that I am limited in my options within native Postman.

I have tried the code below along with some other example code using Crypto-JS to no avail... I always get the wrong 6 digit OTP value. I know the correct, working OTPs for the key and counter combination because I have successfully created a similar utility in C#.

I am trying to use the following code within a Pre-Request Script:

function hotp( key, counter, digits ) {

  const buffer = Buffer.alloc(8);
  for (let i = 0; i < 8; i++) {
      buffer[7 - i] = counter & 0xff;
      counter = counter >> 8;
  }
  
  const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA1, key); 
  hmac.update(CryptoJS.lib.WordArray.create(buffer));

  return zeropad(truncate(Buffer.from(hmac.finalize().toString(), 'hex'), digits), digits);

    function zeropad( value, digits = 16 ) {
        var fill = '0'.repeat( digits )
    return ( fill + value ).slice( -digits )
    }

    function truncate( hmac, digits ) {
    var offset = hmac[ hmac.length - 1 ] & 0x0F
    var value = ( hmac[ offset + 0 ] & 0x7F ) << 24 |
        ( hmac[ offset + 1 ] & 0xFF ) << 16 |
        ( hmac[ offset + 2 ] & 0xFF ) <<  8 |
        ( hmac[ offset + 3 ] & 0xFF )
    return value % ( 10 ** digits )
    }
}

var key = "10f869eadb33edf1160477cfcc503d875aeaa17c"; - example key
var counter = 0;

The values generated for counters 0-8 come out as: 962076 661983 564874 692146 270493 542260 345608 998477 964548

However these values do not work against the application backend. I've successfully done this same algorithm in C# and get the OTPs to be accepted.

The correct OTP values for counters 0-8 should be: 529311 627331 461764 308872 837476 597284 520251 728342 407976

Can anyone see what I am doing wrong here?


Solution

  • I added the following line above my hmac creation call and passed the newly encoded key value to the hmac create function in order to get the proper results.

    var wordKey = CryptoJS.enc.Hex.parse(key);

    This was all that was missing to get the values I was looking for.