Click here to Skip to main content
Full site     10M members (31.5K online)    

OTP (One Time Password) Demystified - Part 1

Introduction

At the beginning of 2004, I was working with a small team of Gemplus on the EAP-SIM authentication protocol. As we were a bit ahead of the market, our team was reassigned to work with a team of Verisign on a new authentication method: OTP or One Time Password.

At this time, the existing one time password was a token from RSA that was using a clock to synchronize the passwords.

The lab of Versign came with a very simple but I should say very smart concept. The OTP that you may be using with your bank or Google was born.

This is this algorithm and authentication method I describe in the following two articles. In this article, I present a complete code of the OTP generator. It is very similar to the Javacard Applet I wrote in 2004 when I started to work on this concept with the Versign labs.

The One Time Password Generator

This OTP is based on the very popular algorithm HMAC SHA. The HMAC SHA is an algorithm generally used to perform authentication by challenge response. It is not an encryption algorithm but a hashing algorithm that transforms a set of bytes to another set of bytes. This algorithm is not reversible which means that you cannot use the result to go back to the source.

A HMAC SHA uses a key to transform an input array of bytes. The key is the secret that must never be accessible to a hacker and the input is the challenge. This means that OTP is a challenge response authentication.

The secret key must be 20 bytes at least; the challenge is usually a counter of 8 bytes which leaves quite some time before the value is exhausted.

The algorithm takes the 20 bytes key and the 8 bytes counter to create a 8 digits number. This means that there will obviously be duplicates during the life time of the OTP generator but this doesn't matter as no duplicate can occur consecutively and an OTP is only valid for a couple of minutes.

Why is the OTP a very strong authentication method?

There are few reasons why this is a very strong method.

Those few characteristics make the OTP a strong authentication protocol. The weakness in an authentication is usually the human factor. It is difficult to remember many complex passwords, so users often use the same one all across the internet and not really a strong one. With an OTP, you don't have to remember a password, the most you would have to remember would be PIN code (4 to 8 digits) if the OTP token is PIN protected. In the case of an OTP sent by a mobile phone, it is protected by your phone security. A PIN is short but you can't generally try it more than 3 times before the token is locked.

The weakness of an OTP if there is one, is the media used to generate or receive the OTP. If the user loses it, then the authentication could be compromised. A possible solution would be to protect this device with a biometric credential, making it virtually totally safe.

The code of the OTP generator follows:

public class OTP
{
    public const int SECRET_LENGTH = 20;
    private const string
	MSG_SECRETLENGTH = "Secret must be at least 20 bytes",
	MSG_COUNTER_MINVALUE = "Counter min value is 1";

    public OTP()
    {
    }

    private static int[] dd = new int[10] { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 }; 

    private byte[] secretKey = new byte[SECRET_LENGTH] 
    {
	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
	0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43
    };

    private ulong counter = 0x0000000000000001;

    private static int checksum(int Code_Digits) 
    {
	int d1 = (Code_Digits/1000000) % 10;
	int d2 = (Code_Digits/100000) % 10;
	int d3 = (Code_Digits/10000) % 10;
	int d4 = (Code_Digits/1000) % 10;
	int d5 = (Code_Digits/100) % 10;
	int d6 = (Code_Digits/10) % 10;
	int d7 = Code_Digits % 10;
	return (10 - ((dd[d1]+d2+dd[d3]+d4+dd[d5]+d6+dd[d7]) % 10) ) % 10;
    }

    /// <summary>
    /// Formats the OTP. This is the OTP algorithm.
    /// </summary>
    /// <param name="hmac">HMAC value</param>
    /// <returns>8 digits OTP</returns>
    private static string FormatOTP(byte[] hmac)
    {
	int offset =  hmac[19] & 0xf ;
	int bin_code = (hmac[offset]   & 0x7f) << 24
		| (hmac[offset+1] & 0xff) << 16
		| (hmac[offset+2] & 0xff) <<  8
		| (hmac[offset+3] & 0xff) ;
	int Code_Digits = bin_code % 10000000;
	int csum = checksum(Code_Digits);
	int OTP = Code_Digits * 10 + csum;

	return string.Format("{0:d08}", OTP);
    }

    public byte[] CounterArray
    {
	get
	{
	    return BitConverter.GetBytes(counter);
	}

	set
	{
	    counter = BitConverter.ToUInt64(value, 0);
	}
    }

    /// <summary>
    /// Sets the OTP secret
    /// </summary>
    public byte[] Secret
    {
	set
	{
	    if (value.Length < SECRET_LENGTH)
	    {
		throw new Exception(MSG_SECRETLENGTH);
	    }

	    secretKey = value;
	}
    }

    /// <summary>
    /// Gets the current OTP value
    /// </summary>
    /// <returns>8 digits OTP</returns>
    public string GetCurrentOTP()
    {
	HmacSha1 hmacSha1 = new HmacSha1();

	hmacSha1.Init(secretKey);
	hmacSha1.Update(CounterArray);
		
	byte[] hmac_result = hmacSha1.Final();

	return FormatOTP(hmac_result);
    }

    /// <summary>
    /// Gets the next OTP value
    /// </summary>
    /// <returns>8 digits OTP</returns>
    public string GetNextOTP()	
    {
	// increment the counter
	++counter;

	return GetCurrentOTP();
    }

    /// <summary>
    /// Gets/sets the counter value
    /// </summary>
    public ulong Counter
    {
	get
	{
	    return counter;
	}

	set
	{
	    counter = value;
	}
    }
}

The methods FormatOTP() and checksum() are the heart of the OTP algorithm. Those methods transform the result of the hmacsha into an 8 digits OTP.

The attached code also contains an implementation of the HMAC SHA algorithm. It is of course possible to use the standard hmacsha of the .NET Framework but the code I provide in fact used a demo in a prototype of smart card that was running a .NET CLR. At the time I wrote this code, the cryptography namespace was not yet implemented by the card.

This way, you can also see how a hmacsha algorithm is implemented.

The OTP Server and Authentication Protocol

An OTP authentication can be done in 2 ways. Using an OTP token or receiving an OTP number on your mobile. In both cases, there is in the back-end an OTP server.

In a second article, I will describe how this OTP server works and is able to resynchronize if you enter some wrong OTP code or use your OTP token without verifying the code with the server.

Getting the Source

You can get the source code of the project from the ZIP files attached to the article or you can follow it on github where it will be updated regularly as this is a public repository.

Points of Interest

OTP is a popular and quite simple authentication method; I hope those articles will help you understand how it works behind the scenes.

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search 
Per page   
-- There are no messages in this forum --

Last Updated 13 May 2013 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2013