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.
- The key is 20 digits
- A password is a couple counter/password, only valid once and a very short time
- The algorithm that generates each password is not reversible
- With an OTP token, the key is hardware protected
- If the OTP is received on your phone, the key always stays at the server
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;
}
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);
}
}
public byte[] Secret
{
set
{
if (value.Length < SECRET_LENGTH)
{
throw new Exception(MSG_SECRETLENGTH);
}
secretKey = value;
}
}
public string GetCurrentOTP()
{
HmacSha1 hmacSha1 = new HmacSha1();
hmacSha1.Init(secretKey);
hmacSha1.Update(CounterArray);
byte[] hmac_result = hmacSha1.Final();
return FormatOTP(hmac_result);
}
public string GetNextOTP()
{
++counter;
return GetCurrentOTP();
}
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.