Archived Forum Post

Index of archived forum posts

Question:

HMAC Sha1 TOTP algorithm

Jan 21 '13 at 21:32

With reference to http://tools.ietf.org/html/rfc6238, this document describes an extension of the One-Time Password (OTP)algorithm, namely the HMAC-based One-Time Password (HOTP) algorithm, as defined in RFC 4226, to support the time-based moving factor.

Basically, the output of the HMAC-SHA-1 calculation is truncated to obtain user-friendly values:

  HOTP(K,C) = Truncate(HMAC-SHA-1(K,C))

The test token shared secret uses the ASCII string value "12345678901234567890". With Time Step X = 30, and the Unix epoch as the initial value to count time steps, where T0 = 0, the TOTP algorithm will display the following values for specified modes and timestamps.

Test Vector :

+-------------+--------------+------------------+----------+--------+

| Time (sec) | UTC Time | Value of T (hex) | TOTP | Mode |

+-------------+--------------+------------------+----------+--------+

| 59 | 1970-01-01 | 0000000000000001 | 94287082 | SHA1 |

My Test Program :

crypt.put_HashAlgorithm("sha-1");
crypt.put_EncodingMode("hex");
crypt.SetHmacKeyEncoded("12345678901234567890","ascii");
 mac = crypt.hmacStringENC("0000000000000001"); // 59/30 = 1 => value of T
printf("blank hex %s\n",mac);
strcpy(hmac_result,mac);
offset   =  hmac_result[19] & 0xf ; //obtain offset to get starting bytes from hmac_result
bin_code = (hmac_result[offset]  & 0x7f) << 24
       | (hmac_result[offset+1] & 0xff) << 16
       | (hmac_result[offset+2] & 0xff) <<  8
       | (hmac_result[offset+3] & 0xff) ;
TOTP = bin_code%(100000000); // extract 8 digits 
printf("TOTP %d\n",TOTP);

TOTP = 10570038 // Not equal to the test vector 94287082

Is the problem due to my encoding selection ? Please advise. Thanks in advance.

Best regards Chilkatsoft Trial User


Answer

The code that computes the HMAC-SHA1 should look like this:

    CkCrypt2 crypt;
...

crypt.put_HashAlgorithm("sha-1");
crypt.put_EncodingMode("hex");
crypt.SetHmacKeyEncoded("12345678901234567890","ascii");

CkByteData counterBytes;
counterBytes.appendCharN('\0',7);
counterBytes.appendChar(1);

printf("%s\n",crypt.hmacBytesENC(counterBytes));

You can verify the HMAC output using the test vectors from RFC 4226:

Appendix D - HOTP Algorithm: Test Values

The following test data uses the ASCII string "12345678901234567890" for the secret:

Secret = 0x3132333435363738393031323334353637383930

Table 1 details for each count, the intermediate HMAC value.

Count Hexadecimal HMAC-SHA-1(secret, count) 0 cc93cf18508d94934c64b65d8ba7667fb7cde4b0 1 75a48a19d4cbe100644e8ac1397eea747a2d33ab 2 0bacb7fa082fef30782211938bc1c5e70416ff44 3 66c28227d03a2d5529262ff016a1e6ef76557ece 4 a904c900a64b35909874b33e61c5938a8e15ed1c 5 a37e783d7b7233c083d4f62926c7a25f238d0316 6 bc9cd28561042c83f219324d3c607256c03272ae 7 a4fb960c0bc06e1eabb804e5b397cdc4b45596fa 8 1b3c89f65e6c9e883012052823443f048b4332db 9 1637409809a679dc698207310c8c7fc07290d9e5


Answer

Thanks for your reply and solution to my question.

Suggestion :

Existing functions=>

crypt.put_HashAlgorithm("sha-1");

crypt.put_EncodingMode("hex");

crypt.SetHmacKeyEncoded("12345678901234567890","ascii");

Is it possible to add the following functions to your future release :

Example ...

crypt.SetHmacMessageEncoded("0000000000000001","hex");

printf("%sn",crypt.hmacEncrypt());

OR

printf("%sn",crypt.hmacEncryptEncoded("hex")); //if not specified crypt.put_EncodingMode("hex");

Hope that my suggestion can be accepted.

Thanks in advance.

Best regards

Chilkat Trial User