Internet Engineering Task Force D. M'Raihi
Internet-Draft Verisign, Inc.
Intended status: Standards Track S. Machani
Expires: June 13, 2010 Diversinet Corp.
M. Pei
Verisign, Inc.
J. Rydell
Portwise, Inc.
December 10, 2009
TOTP: Time-based One-time Password Algorithm
draft-mraihi-totp-timebased-04.txt
Abstract
This document describes an extension of one-time password algorithm
HOTP as defined in [RFC4226] to support time based moving factor.
Status of this Memo
This Internet-Draft is submitted to IETF in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF), its areas, and its working groups. Note that
other groups may also distribute working documents as Internet-
Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt.
The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html.
This Internet-Draft will expire on June 13, 2010.
Copyright Notice
Copyright (c) 2009 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
M'Raihi, et al. Expires June 13, 2010 [Page 1]
Internet-Draft HOTPTimeBased December 2009
Provisions Relating to IETF Documents
(http://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as
described in the BSD License.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Scope . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2. Background . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Notation and Terminology . . . . . . . . . . . . . . . . . . . 3
3. Algorithm Requirements . . . . . . . . . . . . . . . . . . . . 3
4. TOTP Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 4
4.1. Notations . . . . . . . . . . . . . . . . . . . . . . . . 4
4.2. Description . . . . . . . . . . . . . . . . . . . . . . . 4
5. Security Considerations . . . . . . . . . . . . . . . . . . . 4
5.1. General . . . . . . . . . . . . . . . . . . . . . . . . . 5
5.2. Validation and Time-step Size . . . . . . . . . . . . . . 5
6. Resynchronization . . . . . . . . . . . . . . . . . . . . . . 6
7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 7
8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 7
9. References . . . . . . . . . . . . . . . . . . . . . . . . . . 7
9.1. Normative references . . . . . . . . . . . . . . . . . . . 7
9.2. Informative References . . . . . . . . . . . . . . . . . . 8
Appendix A. TOTP Algorithm: Reference Implementation . . . . . . 8
Appendix B. Test Vectors . . . . . . . . . . . . . . . . . . . . 13
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 14
M'Raihi, et al. Expires June 13, 2010 [Page 2]
Internet-Draft HOTPTimeBased December 2009
1. Introduction
1.1. Scope
This document describes an extension of one-time password algorithm
HOTP as defined in [RFC4226] to support time based moving factor.
1.2. Background
As defined in [RFC4226] the HOTP algorithm is based on the HMAC-SHA-1
algorithm, as specified in [RFC2104] applied to an increasing counter
value representing the message in the HMAC computation.
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))
where Truncate represents the function that can convert an HMAC-SHA-1
value into an HOTP value.
TOTP is the time-based variant of this algorithm where a value T
derived from a time reference and a time step replaces the counter C
in the HOTP computation.
The default HMAC-SHA-1 function could be replaced by HMAC-SHA-256 or
HMAC-SHA-512 to leverage HMAC implementations based on SHA-256 or
SHA-512 hash functions.
2. Notation and Terminology
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC2119]
3. Algorithm Requirements
This section summarizes the requirements taken into account for
designing the TOTP algorithm.
R1 - The prover (e.g. token, soft token) and verifier (authentication
or validation server) MUST have access to the Unix Time
R2 - The prover and verifier MUST either share a same secret or the
knowledge of a secret transformation to generate a shared secret
M'Raihi, et al. Expires June 13, 2010 [Page 3]
Internet-Draft HOTPTimeBased December 2009
R3 - The algorithm MUST use HOTP [RFC4226] as a key building block.
R4 - The prover and verifier MUST use the same time step value X.
R5 - There MUST be a unique secret (key) for each prover.
R6 - The keys SHOULD be randomly generated or derived using a key
derivation algorithms.
R7 - The keys MAY be stored in a tamper-resistant device and SHOULD
be protected against unauthorized access and usage.
R8 - The TOTP algorithm SHOULD be used for online application.
4. TOTP Algorithm
This variant of the HOTP algorithm specifies the calculation of a
one-time password value, based on a representation of the counter as
a time factor.
4.1. Notations
- X represents the time step in seconds (default value X = 30
seconds) and is a system parameter;
- T0 is the Unix time to start counting time steps (default value is
0, Unix epoch) and is also a system parameter.
4.2. Description
Basically, we define TOTP as TOTP = HOTP(K, T) where T is an integer
and represents the number of time steps between the initial counter
time T0 and the current Unix time (i.e. the number of seconds elapsed
since midnight UTC of January 1, 1970).
More specifically T = (Current Unix time - T0) / X where:
- X represents the time step in seconds (default value X = 30
seconds) and is a system parameter;
- T0 is the Unix time to start counting time steps (default value is
0, Unix epoch) and is also a system parameter.
5. Security Considerations
M'Raihi, et al. Expires June 13, 2010 [Page 4]
Internet-Draft HOTPTimeBased December 2009
5.1. General
The security and strength of this algorithm depends on the properties
of the underlying building block HOTP, which is a construction based
on HMAC [RFC2104] using SHA-1 as the hash function.
The conclusion of the security analysis detailed in [RFC4226] is
that, for all practical purposes, the outputs of the dynamic
truncation on distinct inputs are uniformly and independently
distributed strings.
The analysis demonstrates that the best possible attack against the
HOTP function is the brute force attack.
As indicated in the algorithm requirement section, keys SHOULD be
chosen at random or using a cryptographically strong pseudo-random
generator properly seeded with a random value.
Keys SHOULD be of the length of the HMAC output to facilitate
interoperability.
We RECOMMEND following the recommendations in [RFC1750] for all
pseudo-random and random generations. The pseudo-random numbers used
for generating the keys SHOULD successfully pass the randomness test
specified in [CN] or a similar well-recognized test.
All the communications SHOULD take place over a secure channel e.g.
SSL/TLS, IPsec connections.
We also RECOMMEND storing the keys securely in the validation system,
and more specifically encrypting them using tamper-resistant hardware
encryption and exposing them only when required: for example, the key
is decrypted when needed to verify an OTP value, and re-encrypted
immediately to limit exposure in the RAM for a short period of time.
The key store MUST be in a secure area, to avoid as much as possible
direct attack on the validation system and secrets database.
Particularly, access to the key material should be limited to
programs and processes required by the validation system only.
5.2. Validation and Time-step Size
An OTP generated within the same Time-step will be the same. When an
OTP is received at a validation system, it doesn't know a client's
exact timestamp when an OTP was generated. The validation system may
typically use the timestamp when an OTP is received for OTP
comparison. Due to the network latency for an OTP to transmit from a
requesting application to a validation system and user's actual input
M'Raihi, et al. Expires June 13, 2010 [Page 5]
Internet-Draft HOTPTimeBased December 2009
time of an OTP to a receiving system, such timestamp gap between the
actual OTP generation time and server's receiving time may be large.
The receiving time at the validation system and the actual OTP
generation may not fall within the same Time-step window that produce
the same OTP. When an OTP is generated at the end of a Time-step
window, the receiving time most likely falls into the next Time-step
window. A validation system SHOULD typically set a policy for an
acceptable OTP transmission delay window for validation. The
validation system should compare OTPs not only with the receiving
timestamp but also the past timesteps that are within the
transmission delay. A larger acceptable delay window would introduce
some OTP attack window. We RECOMMEND that at most one time step is
allowed as the network delay.
The Time-step size has impact on both security and usability. A
larger Time-step size means larger validity window for an OTP to be
accepted by a validation system. There are the following
implications with a larger Time-step size.
At first, a larger Time-step size exposes larger window for attack.
When an OTP is generated and exposed to a third party before it is
consumed, the third party can consume the OTP within the Time-step
window.
We RECOMMEND default Time-step size for 30 seconds.
Secondly, the next different OTP must be generated in the next Time-
step window. A user must wait till the clock moves to the next Time-
step window from the last submission. The waiting time may not be
exactly the length of Time-step depending on when the last OTP was
generated. For example, if the last OTP was generated at the half
way in a Time-step window, the waiting time for the next OTP is half
of length of Time-step. In general, a larger Time-step window means
larger waiting time for a user to get the next valid OTP after the
last successfully OTP validation. A too large window, for example 10
minutes, most probably won't be suitable for typical internet login
use cases; a user may not be able to get the next OTP within 10
minutes and therefore re-login back to the same site in 10 minutes.
The default Time-step size 30 seconds is recommended.
6. Resynchronization
Because of possible clock drifts between a client and a validation
server, we RECOMMEND that the validator be set with a specific limit
to the number of time steps a prover can be 'out of synch' before
being not validated/rejected.
M'Raihi, et al. Expires June 13, 2010 [Page 6]
Internet-Draft HOTPTimeBased December 2009
This limit can be set both forward and backwards from the calculated
time step on receipt of the OTP value. If the time step is 30
seconds as recommended, and the validator is set to only accept 2
time step backwards then the maximum elapsed time drift would be
around 89 seconds, i.e. 29 seconds in the calculated time step and 60
for two backward time steps.
This would mean the validator could perform a validation against the
current time and then further two validations for each backward step
(for a total of 3 validations). Upon successful validation, the
validation server can record the detected clock drift for the token
in terms of number of Time-step. When a new OTP is received after
this step, the validator can validate the OTP with current timestamp
adjusted with recorded number of Time-step clock drifts for the
token.
Also, it is important to note that the longer a prover has not sent
an OTP to a validation system, the longer (potentially) the
accumulated clock drift between the prover and the verifier. In such
cases, the default synchronization may not be proper when the drift
exceeds beyond allowed threshold. Additional authentication measures
SHOULD be used for the validation system to safely authenticate the
prover.
7. IANA Considerations
The OTP algorithm defined in this document can be referred by a URI
defined in a separate document. There is no registration needed in
this document.
8. Acknowledgements
The authors of this draft would like to thank the following people
for their contributions and support to make this a better
specification: Jonathan Tuliani, David Dix, Siddharth Bajaj, Stu
Veath, Shuh Chang, Oanh Hoang, John Huang, and Siddhartha Mohapatra.
9. References
9.1. Normative references
[RFC1750] Eastlake, D., Crocker, S., and J. Schiller, "Randomness
Recommendations for Security", RFC 1750, December 1994,
<http://www.ietf.org/rfc/rfc1750.txt>.
M'Raihi, et al. Expires June 13, 2010 [Page 7]
Internet-Draft HOTPTimeBased December 2009
[RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-
Hashing for Message Authentication", RFC 2104,
February 1997, <http://www.ietf.org/rfc/rfc2104.txt>.
[RFC2119] "Key words for use in RFCs to Indicate Requirement
Levels", BCP 14, RFC 2119, March 1997,
<http://www.ietf.org/rfc/rfc2119.txt>.
[RFC4226] M'Raihi, D., Bellare, M., Hoornaert, F., Naccache, D., and
O. Ranen, "HOTP: An HMAC-Based One-Time Password
Algorithm", RFC 4226, December 2005,
<http://www.ietf.org/rfc/rfc4226.txt>.
9.2. Informative References
[CN] Coron, J. and D. Naccache, "An accurate evaluation of
Maurer's universal test", LNCS 1556, February 1999, <http:
//www.gemplus.com/smart/rd/publications/pdf/CN99maur.pdf>.
Appendix A. TOTP Algorithm: Reference Implementation
import java.lang.reflect.UndeclaredThrowableException;
import java.security.GeneralSecurityException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.util.TimeZone;
/**
* This an example implementation of the OATH TOTP algorithm.
* Visit www.openauthentication.org for more information.
*
* @author Johan Rydell, PortWise, Inc.
*/
public class TOTP {
private TOTP() {}
/**
* This method uses the JCE to provide the crypto
* algorithm.
M'Raihi, et al. Expires June 13, 2010 [Page 8]
Internet-Draft HOTPTimeBased December 2009
* HMAC computes a Hashed Message Authentication Code with the
* crypto hash algorithm as a parameter.
*
* @param crypto the crypto algorithm (HmacSHA1, HmacSHA256, HmacSHA512)
* @param keyBytes the bytes to use for the HMAC key
* @param text the message or text to be authenticated.
*/
private static byte[] hmac_sha1(String crypto, byte[] keyBytes, byte[] text)
{
try {
Mac hmac;
hmac = Mac.getInstance(crypto);
SecretKeySpec macKey =
new SecretKeySpec(keyBytes, "RAW");
hmac.init(macKey);
return hmac.doFinal(text);
} catch (GeneralSecurityException gse) {
throw new UndeclaredThrowableException(gse);
}
}
/**
* This method converts HEX string to Byte[]
*
* @param hex the HEX string
*
* @return A byte array
*/
private static byte[] hexStr2Bytes(String hex){
// Adding one byte to get the right conversion
// values starting with "0" can be converted
byte[] bArray = new BigInteger("10" + hex,16).toByteArray();
// Copy all the REAL bytes, not the "first"
byte[] ret = new byte[bArray.length - 1];
for (int i = 0; i < ret.length ; i++)
ret[i] = bArray[i+1];
return ret;
}
private static final int[] DIGITS_POWER
// 0 1 2 3 4 5 6 7 8
= {1,10,100,1000,10000,100000,1000000,10000000,100000000 };
/**
M'Raihi, et al. Expires June 13, 2010 [Page 9]
Internet-Draft HOTPTimeBased December 2009
* This method generates an TOTP value for the given
* set of parameters.
*
* @param key the shared secret, HEX encoded
* @param time a value that reflects a time
* @param returnDigits number of digits to return
* @param crypto the crypto function to use
*
* @return A numeric String in base 10 that includes
* {@link truncationDigits} digits
*/
public static String generateTOTP(String key,
String time,
String returnDigits)
{
return generateTOTP(key, time, returnDigits, "HmacSHA1");
}
/**
* This method generates an TOTP value for the given
* set of parameters.
*
* @param key the shared secret, HEX encoded
* @param time a value that reflects a time
* @param returnDigits number of digits to return
* @param crypto the crypto function to use
*
* @return A numeric String in base 10 that includes
* {@link truncationDigits} digits
*/
public static String generateTOTP256(String key,
String time,
String returnDigits)
{
return generateTOTP(key, time, returnDigits, "HmacSHA256");
}
/**
* This method generates an TOTP value for the given
* set of parameters.
*
* @param key the shared secret, HEX encoded
* @param time a value that reflects a time
* @param returnDigits number of digits to return
* @param crypto the crypto function to use
*
M'Raihi, et al. Expires June 13, 2010 [Page 10]
Internet-Draft HOTPTimeBased December 2009
* @return A numeric String in base 10 that includes
* {@link truncationDigits} digits
*/
public static String generateTOTP512(String key,
String time,
String returnDigits)
{
return generateTOTP(key, time, returnDigits, "HmacSHA512");
}
/**
* This method generates an TOTP value for the given
* set of parameters.
*
* @param key the shared secret, HEX encoded
* @param time a value that reflects a time
* @param returnDigits number of digits to return
* @param crypto the crypto function to use
*
* @return A numeric String in base 10 that includes
* {@link truncationDigits} digits
*/
private static String generateTOTP(String key,
String time,
String returnDigits,
String crypto)
{
int codeDigits = Integer.decode(returnDigits).intValue();
String result = null;
byte[] hash;
// Using the counter
// First 8 bytes are for the movingFactor
// Complaint with base RFC 4226 (HOTP)
while(time.length() < 16 )
time = "0" + time;
// Get the HEX in a Byte[]
byte[] msg = hexStr2Bytes(time);
// Adding one byte to get the right conversion
byte[] k = hexStr2Bytes(key);
hash = hmac_sha1(crypto, k, msg);
// put selected bytes into result int
int offset = hash[hash.length - 1] & 0xf;
M'Raihi, et al. Expires June 13, 2010 [Page 11]
Internet-Draft HOTPTimeBased December 2009
int binary =
((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) |
((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff);
int otp = binary % DIGITS_POWER[codeDigits];
result = Integer.toString(otp);
while (result.length() < codeDigits) {
result = "0" + result;
}
return result;
}
public static void main(String[] args) {
String seed = "3132333435363738393031323334353637383930";
long testTime[] = {1111111109, 1111111111, 1234567890, 2000000000};
String time = "0";
Date myDate = Calendar.getInstance().getTime();
BigInteger b = new BigInteger("0");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
try{
System.out.println("+--------------+-----------------------+------------------+--------+--------+");
System.out.println("| Time(sec) | Time (UTC format) | Value of T(Hex) | TOTP | Mode |");
System.out.println("+--------------+-----------------------+------------------+--------+--------+");
for(int i=0; i<testTime.length; i++) {
myDate.setTime(testTime[i]*1000);
b = new BigInteger("0" + myDate.getTime());
b = b.divide(new BigInteger("30000"));
time = b.toString(16).toUpperCase();
while(time.length() < 16) time = "0" + time;
System.out.print("| " + testTime[i] + " | " + df.format(myDate) + " |");
System.out.print(" " + time + " |");
System.out.println(generateTOTP(seed, time, "8", "HmacSHA1") + "| SHA1 |");
System.out.print("| " + testTime[i] + " | " + df.format(myDate) + " |");
System.out.print(" " + time + " |");
System.out.println(generateTOTP(seed, time, "8", "HmacSHA256") + "| SHA256 |");
System.out.print("| " + testTime[i] + " | " + df.format(myDate) + " |");
System.out.print(" " + time + " |");
System.out.println(generateTOTP(seed, time, "8", "HmacSHA512") + "| SHA512 |");
System.out.println("+--------------+-----------------------+------------------+--------+--------+");
}
}catch (final Exception e){
M'Raihi, et al. Expires June 13, 2010 [Page 12]
Internet-Draft HOTPTimeBased December 2009
System.out.println("Error : " + e);
}
}
}
Appendix B. Test Vectors
This section provides test values that can be used for HOTP time-
based variant algorithm interoperability test.
The test token shared secret uses the ASCII string value
"12345678901234567890". With Time Step X = 30, and Unix epoch as
initial value to count time steps where T0 = 0, the TOTP algorithm
will display the following values for specified modes and timestamps.
+------------+---------------+------------------+----------+--------+
| Time (sec) | UTC Time | Value of T (hex) | TOTP | Mode |
+------------+---------------+------------------+----------+--------+
| 1111111109 | 2005-03-18 | 00000000023523EC | 07081804 | SHA1 |
| | 01:58:29 | | | |
| 1111111109 | 2005-03-18 | 00000000023523EC | 34756375 | SHA256 |
| | 01:58:29 | | | |
| 1111111109 | 2005-03-18 | 00000000023523EC | 63049338 | SHA512 |
| | 01:58:29 | | | |
| 1111111111 | 2005-03-18 | 00000000023523ED | 14050471 | SHA1 |
| | 01:58:31 | | | |
| 1111111111 | 2005-03-18 | 00000000023523ED | 74584430 | SHA256 |
| | 01:58:31 | | | |
| 1111111111 | 2005-03-18 | 00000000023523ED | 54380122 | SHA512 |
| | 01:58:31 | | | |
| 1234567890 | 2009-02-13 | 000000000273EF07 | 89005924 | SHA1 |
| | 23:31:30 | | | |
| 1234567890 | 2009-02-13 | 000000000273EF07 | 42829826 | SHA256 |
| | 23:31:30 | | | |
| 1234567890 | 2009-02-13 | 000000000273EF07 | 76671578 | SHA512 |
| | 23:31:30 | | | |
| 2000000000 | 2033-05-18 | 0000000003F940AA | 69279037 | SHA1 |
| | 03:33:20 | | | |
| 2000000000 | 2033-05-18 | 0000000003F940AA | 78428693 | SHA256 |
| | 03:33:20 | | | |
| 2000000000 | 2033-05-18 | 0000000003F940AA | 56464532 | SHA512 |
| | 03:33:20 | | | |
+------------+---------------+------------------+----------+--------+
Table 1: TOTP Table
M'Raihi, et al. Expires June 13, 2010 [Page 13]
Internet-Draft HOTPTimeBased December 2009
Authors' Addresses
David M'Raihi
Verisign, Inc.
685 E. Middlefield Road
Mountain View, CA 94043
USA
Email: dmraihi@verisign.com
Salah Machani
Diversinet Corp.
2225 Sheppard Avenue East, Suite 1801
Toronto, Ontario M2J 5C2
Canada
Email: smachani@diversinet.com
Mingliang Pei
Verisign, Inc.
685 E. Middlefield Road
Mountain View, CA 94043
USA
Email: mpei@verisign.com
Johan Rydell
Portwise, Inc.
275 Hawthorne Ave, Suite 119
Palo Alto, CA 94301
USA
Email: johan.rydell@portwise.com
M'Raihi, et al. Expires June 13, 2010 [Page 14]