Internet Engineering Task Force D. M'Raihi Internet-Draft Verisign, Inc. Intended status: Standards Track S. Machani Expires: September 28, 2008 Diversinet Corp. M. Pei Verisign, Inc. J. Rydell Portwise, Inc. March 27, 2008 TOTP: Time-based One-time Password Algorithm draft-mraihi-totp-timebased-00.txt Status of this Memo By submitting this Internet-Draft, each author represents that any applicable patent or other IPR claims of which he or she is aware have been or will be disclosed, and any of which he or she becomes aware will be disclosed, in accordance with Section 6 of 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 September 28, 2008. Abstract This document describes an extension of one-time password algorithm HOTP as defined in [RFC4226] to support time based moving factor. M'Raihi, et al. Expires September 28, 2008 [Page 1] Internet-Draft HOTPTimeBased March 2008 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 . . . . . . . . . . . . . . . . . . . . . . . . . 4 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 . . . . . . . . . . . . . . . . . . . . 12 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 12 Intellectual Property and Copyright Statements . . . . . . . . . . 14 M'Raihi, et al. Expires September 28, 2008 [Page 2] Internet-Draft HOTPTimeBased March 2008 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. 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 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. M'Raihi, et al. Expires September 28, 2008 [Page 3] Internet-Draft HOTPTimeBased March 2008 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 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. M'Raihi, et al. Expires September 28, 2008 [Page 4] Internet-Draft HOTPTimeBased March 2008 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. 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 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 M'Raihi, et al. Expires September 28, 2008 [Page 5] Internet-Draft HOTPTimeBased March 2008 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. 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 M'Raihi, et al. Expires September 28, 2008 [Page 6] Internet-Draft HOTPTimeBased March 2008 (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 A URI should be registered for the OTP algorithm defined in this document. The following URI should be used to refer to this TOTP algorithm: TBD: http://www.ietf.org/rfc/totp 8. Acknowledgements TBD 9. References 9.1. Normative references [RFC1750] Eastlake, D., Crocker, S., and J. Schiller, "Randomness Recommendations for Security", RFC 1750, December 1994, . [RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed- Hashing for Message Authentication", RFC 2104, February 1997, . [RFC2119] "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997, . [RFC4226] M'Raihi, D., Bellare, M., Hoornaert, F., Naccache, D., and O. Ranen, "HOTP: An HMAC-Based One-Time Password M'Raihi, et al. Expires September 28, 2008 [Page 7] Internet-Draft HOTPTimeBased March 2008 Algorithm", RFC 4226, December 2005, . 9.2. Informative References [CN] Coron, J. and D. Naccache, "An accurate evaluation of Maurer's universal test", LNCS 1556, February 1999, . 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 */ public class TOTP { private TOTP() {} /** * This method uses the JCE to provide the crypto * algorithm. * 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. */ public static byte[] hmac_sha1(String crypto, byte[] keyBytes, byte[] text) { try { Mac hmac; M'Raihi, et al. Expires September 28, 2008 [Page 8] Internet-Draft HOTPTimeBased March 2008 hmac = Mac.getInstance(crypto); SecretKeySpec macKey = new SecretKeySpec(keyBytes, "RAW"); hmac.init(macKey); return hmac.doFinal(text); } catch (GeneralSecurityException gse) { throw new UndeclaredThrowableException(gse); } } private static final int[] DIGITS_POWER // 0 1 2 3 4 5 6 7 8 = {1,10,100,1000,10000,100000,1000000,10000000,100000000 }; /** * 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 return digits * * @return A numeric String in base 10 that includes * {@link truncationDigits} digits */ static public String generateTOTP(String key, String time, String returnDigits) { int codeDigits = Integer.decode(returnDigits); String crypto = "HmacSHA1"; String result = null; byte[] bArray; byte[] msg = new byte[8]; // Put the bytes of "time" to the message // Input is the HEX value of "time" if(time.length() > 0){ bArray = new BigInteger(time,16).toByteArray(); if(bArray.length == 9){ // First byte is the "sign" byte for (int i = 0; i < 8 && i < bArray.length ; i++) { msg[i + 8 - bArray.length] = bArray[i+1]; } } else { for (int i = 0; i < 8 && i < bArray.length ; i++) { M'Raihi, et al. Expires September 28, 2008 [Page 9] Internet-Draft HOTPTimeBased March 2008 msg[i + 8 - bArray.length] = bArray[i]; } } } byte[] hash; bArray = new BigInteger(key,16).toByteArray(); if(bArray[0] == 0){ byte[] b = new byte[bArray.length - 1]; for(int i = 0 ; i < b.length; i++) b[i]=bArray[i+1]; hash = hmac_sha1(crypto, b, msg); } else{ // compute hmac hash hash = hmac_sha1(crypto, bArray, msg); } // put selected bytes into result int int offset = hash[hash.length - 1] & 0xf; 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"; 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("| Unix Time | UTC Time | Value of T | OTP |"); System.out.println("+------------+-----------------------+------------------+--------+"); M'Raihi, et al. Expires September 28, 2008 [Page 10] Internet-Draft HOTPTimeBased March 2008 myDate.setTime(Long.parseLong("1000000000000")); System.out.print("| " + myDate.getTime()/1000 + " | " + df.format(myDate) + " |"); 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(" " + time + " | "); System.out.println(generateTOTP(seed, time, "6") + " |"); System.out.println("+------------+-----------------------+------------------+--------+"); myDate.setTime(Long.parseLong("1111111111000")); System.out.print("| " + myDate.getTime()/1000 + " | " + df.format(myDate) + " |"); 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(" " + time + " | "); System.out.println(generateTOTP(seed, time, "6") + " |"); System.out.println("+------------+-----------------------+------------------+--------+"); myDate.setTime(Long.parseLong("1234567890000")); System.out.print("| " + myDate.getTime()/1000 + " | " + df.format(myDate) + " |"); 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(" " + time + " | "); System.out.println(generateTOTP(seed, time, "6") + " |"); System.out.println("+------------+-----------------------+------------------+--------+"); myDate.setTime(Long.parseLong("2000000000000")); System.out.print("| " + myDate.getTime()/1000 + " | " + df.format(myDate) + " |"); 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(" " + time + " | "); System.out.println(generateTOTP(seed, time, "6") + " |"); System.out.println("+------------+-----------------------+------------------+--------+"); M'Raihi, et al. Expires September 28, 2008 [Page 11] Internet-Draft HOTPTimeBased March 2008 }catch (final Exception e){ 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 HOTP time based algorithm will display the following OTP values for corresponding timestamps. +------------+---------------------+------------------+--------+ | Unix Time | UTC Time | Value of C | OTP | +------------+---------------------+------------------+--------+ | 1111111111 | 2005-03-18T01:58:31 | 00000000023523ED | 050471 | | 1234567890 | 2009-02-13T23:31:30 | 000000000273EF07 | 005924 | | 2000000000 | 2033-05-18T03:33:20 | 0000000003F940AA | 279037 | +------------+---------------------+------------------+--------+ Table 1: OTP Table 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 M'Raihi, et al. Expires September 28, 2008 [Page 12] Internet-Draft HOTPTimeBased March 2008 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 September 28, 2008 [Page 13] Internet-Draft HOTPTimeBased March 2008 Full Copyright Statement Copyright (C) The IETF Trust (2008). This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights. This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Intellectual Property The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79. Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr. The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org. M'Raihi, et al. Expires September 28, 2008 [Page 14]