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

Best regards Chilkatsoft Trial User

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.
0        cc93cf18508d94934c64b65d8ba7667fb7cde4b0
1        75a48a19d4cbe100644e8ac1397eea747a2d33ab
2        0bacb7fa082fef30782211938bc1c5e70416ff44
3        66c28227d03a2d5529262ff016a1e6ef76557ece
4        a904c900a64b35909874b33e61c5938a8e15ed1c
5        a37e783d7b7233c083d4f62926c7a25f238d0316
6        bc9cd28561042c83f219324d3c607256c03272ae
7        a4fb960c0bc06e1eabb804e5b397cdc4b45596fa
8        1b3c89f65e6c9e883012052823443f048b4332db
9        1637409809a679dc698207310c8c7fc07290d9e5
```

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.