{{short description|Password authentication algorithm}} {{Multiple issues| {{Lead too short|date=December 2020}} {{Technical|date=December 2020}} }}
'''HMAC-based one-time password''' ('''HOTP''') is a one-time password (OTP) algorithm based upon a hash-based message authentication code (HMAC) . When a client attempts to access a server, a challenge is sent by the destination server to the client. The client then computes a response which represents a one time password. This often forms part of multi-factor authentication protocols such as the Open Authentication initiative (OATH) challenge-response algorithm.<ref>{{Cite report |url=https://datatracker.ietf.org/doc/rfc6287/ |title=OCRA: OATH Challenge-Response Algorithm |last=M'Raihi |first=David |last2=Naccache |first2=David |last3=Rydell |first3=Johan |last4=Bajaj |first4=Siddharth |last5=Machani |first5=Salah |date=June 2011 |publisher=Internet Engineering Task Force |issue=RFC 6287}}</ref>
HOTP was published as an informational IETF {{IETF RFC|4226}} in December 2005, documenting the algorithm along with a Java implementation. Since then, the algorithm has been adopted by many companies worldwide (see below). The HOTP algorithm is a freely available open standard.
== Algorithm == The HOTP algorithm provides a method of authentication by symmetric generation of human-readable passwords, or ''values'', each used for only one authentication attempt. The one-time property leads directly from the single use of each counter value.
Parties intending to use HOTP must establish some {{vanchor|parameters}}; typically these are specified by the authenticator, and either accepted or not by the authenticated entity: * A cryptographic hash method ''H'' (default is SHA-1) * A secret key ''K'', which is an arbitrary byte string and must remain private * A counter ''C'', which is 8 bytes long and counts the number of iterations * A HOTP value length ''d'' (6–10, default is 6, and 6–8 is recommended)
Both parties compute the HOTP value derived from the secret key ''K'' and the counter ''C''. Then the authenticator checks its locally generated value against the value supplied by the authenticated.
The authenticator and the authenticated entity increment the counter ''C'' independently. Since the authenticated entity may increment the counter more than the authenticator, {{IETF RFC|4226}} recommends a resynchronization protocol. It proposes that the authenticator repeatedly try verification ahead of their counter through a window of size ''s''. The authenticator's counter continues forward of the value at which verification succeeds, and requires no actions by the authenticated entity.
To protect against brute-force attacks targeting the small size of HOTP values, the RFC also recommends implementing persistent throttling of HOTP verification. This can be achieved by either locking out verification after a small number of failed attempts, or by linearly increasing the delay after each failed attempt.
6-digit codes are commonly provided by proprietary hardware tokens from a number of vendors informing the default value of ''d''. Truncation extracts 31 bits or <math display="inline">\log_{10}(2^{31}) \approx 9.3</math> decimal digits, meaning that ''d'' can be at most 10, with the 10th digit adding less variation, taking values of 0, 1, and 2 (i.e., 0.3 digits).
After verification, the authenticator can authenticate itself simply by generating the next HOTP value, returning it, and then the authenticated can generate their own HOTP value to verify it. Note that counters are guaranteed to be synchronised at this point in the process.
The ''HOTP value'' is the human-readable design output, a ''d''-digit decimal number (without omission of leading 0s):
: ''HOTP value'' = ''HOTP''(''K'', ''C'') mod 10<sup>''d''</sup>.
That is, the value is the ''d'' least significant base-10 digits of HOTP.
''HOTP'' is a truncation of the HMAC of the counter ''C'' (under the key ''K'' and hash function ''H''):
: ''HOTP''(''K'', ''C'') = truncate(HMAC{{sub|''H''}}(''K'', ''C'')),
where the counter ''C'' must be used big-endian.
Truncation first takes the 4 least significant bits of the ''MAC'' and uses them as a byte offset ''i'':
: truncate(''MAC'') = extract31(''MAC'', ''MAC''[(19 × 8 + 4):(19 × 8 + 7)]),
where ":" is used to extract bits from a starting bit number up to and including an ending bit number, where these bit numbers are 0-origin. The use of "19" in the above formula relates to the size of the output from the hash function. With the default of SHA-1, the output is {{val|20|ul=bytes}}, and so the last byte is byte 19 (0-origin).
That index ''i'' is used to select 31 bits from ''MAC'', starting at bit ''i'' × 8 + 1:
: extract31(''MAC'', ''i'') = ''MAC''[(''i'' × 8 + 1):(''i'' × 8 + 4 × 8 − 1)].
31 bits are a single bit short of a 4-byte word. Thus the value can be placed inside such a word without using the sign bit (the most significant bit). This is done to definitely avoid doing modular arithmetic on negative numbers, as this has many differing definitions and implementations.<ref>{{Cite journal | url=https://tools.ietf.org/html/rfc4226#section-5.3 | title=HOTP: An HMAC-Based One-Time Password Algorithm | first1=Hoornaert | last1=Frank | first2=Naccache | last2=David | first3=Bellare | last3=Mihir | first4=Ranen | last4=Ohad | website=tools.ietf.org | date=December 2005 | doi=10.17487/RFC4226 | url-access=subscription }}</ref>
=== Implementation ===
The following Python code implements the HMAC-SHA1 and HOTP algorithms.
<syntaxhighlight lang="python" line> import hashlib
def hmac_sha1(*, key: bytes, msg: bytes) -> bytes: if len(key) > 64: key = hashlib.sha1(key).digest() else: key = key.ljust(64, b'\0') o_key_pad = bytes(i ^ 0x5c for i in key) i_key_pad = bytes(i ^ 0x36 for i in key) return hashlib.sha1( o_key_pad + hashlib.sha1(i_key_pad + msg).digest() ).digest()
def hotp(*, key: bytes, ctr: int, length: int) -> str: mac = hmac_sha1(key=key, msg=ctr.to_bytes(8, 'big')) offset = mac[-1] & 0xf truncated = bytearray(mac[offset:offset+4]) truncated[0] &= 0x7f value = int.from_bytes(truncated, 'big') % (10**length) return str(value).rjust(length, '0') </syntaxhighlight>
=== <code>otpauth://</code> URI scheme ===
[[File:Example QR code containing a HOTP otpauth URI.png|thumb|The URI mentioned in this section, encoded as a QR code. Many smartphones allow users to scan such codes and enroll them in an authenticator app, such as Google Authenticator.]]
Some implementations of HOTP and TOTP for smartphones allow users to scan QR codes to add HOTP and TOTP tokens to their authenticator apps. These QR codes contain Uniform Resource Identifiers (URIs) with the scheme <code>otpauth://</code>.<ref>{{cite web |last=Habets |first=Thomas |date=2018-11-26 |title=Key Uri Format |url=https://github.com/google/google-authenticator/wiki/Key-Uri-Format |website=GitHub |access-date=2026-05-24}}</ref>
HOTP <code>otpauth://</code> URIs begin with <code>otpauth://hotp/</code> and must contain a label, secret, and counter. The label is encoded as part of the path, while the secret and counter are encoded as query parameters. The URI may optionally contain other fields, such as the number of digits (which defaults to 6), the algorithm used (which defaults to SHA1), and the issuer name.
The secret is encoded as RFC 4648 Base32, with padding omitted. For example, the URI <code>otpauth://hotp/Wikipedian?secret=JBSWY3DPFQQHO33SNRSCC&counter=42</code> represents a HOTP token labeled "Wikipedian", with the secret <code>Hello, world!</code> encoded as ASCII, and the initial counter 42. When added to an authenticator, it should produce the code <code>439256</code>.
== Tokens == Both hardware and software tokens are available from various vendors, for some of them see references below.
Software tokens are available for (nearly) all major mobile/smartphone platforms (J2ME,<ref>{{cite web | work = Data Security Systems Solutions | date = 2006-02-24 | title = DS3 Launches OathToken Midlet Application | url = http://ds3global.com/index.php/en/news-a-events/news/97-securing-data-delivery-hassle-free-/ | url-status = dead | archive-url = https://web.archive.org/web/20131229080741/http://ds3global.com/index.php/en/news-a-events/news/97-securing-data-delivery-hassle-free- | archive-date = 29 December 2013 }}</ref> Android,<ref>{{cite web | year = 2010 | title = StrongAuth | url = http://www.androidzoom.com/android_applications/tools/strongauth_bmeq.html | url-status = dead | archive-url = https://web.archive.org/web/20100518213222/http://www.androidzoom.com/android_applications/tools/strongauth_bmeq.html | archive-date = 2010-05-18 }}</ref> iPhone,<ref>{{cite web | work = Archie L. Cobbs | year = 2010 | first = Archie L. | last= Cobbs | title = OATH Token | url = http://code.google.com/p/oathtoken/ }}</ref> BlackBerry,<ref name="actividentityst">{{cite web | work = ActivIdentity | year = 2010 | title = ActivIdentity Soft Tokens | url = http://www.actividentity.com/products/authenticationdevices/SoftTokens/ | url-status = dead | archive-url = https://web.archive.org/web/20100917040954/http://actividentity.com/products/authenticationdevices/SoftTokens/ | archive-date = 2010-09-17 }}</ref> Maemo,<ref>{{cite web | work = Sean Whitbeck | year = 2011 | first = Sean | last = Whitbeck | title = OTP Generator for N900 | url = http://maemo.org/packages/view/otp/ }}</ref> macOS,<ref>{{cite web | work = Feel Good Software | year = 2011 | title = SecuriToken | url = http://www.feelgoodsoftware.com/ | url-status = dead | archive-url = https://web.archive.org/web/20120425125135/http://www.feelgoodsoftware.com/ | archive-date = 2012-04-25 }}</ref> and Windows Mobile<ref name="actividentityst"/>).
== Reception ==
{{update section|date=August 2023}}
Although the early reception from some of the computer press was negative during 2004 and 2005,<ref>{{cite web | work = Network World | date = 2004-12-06 | first = Dave | last = Kearns | title = Digging deeper into OATH doesn't look so good | url = https://www.networkworld.com/article/2327517/digging-deeper-into-oath-doesn-t-look-so-good.html }}</ref><ref>{{cite web | work = Computerworld | date = 2005-03-21 | first = Mark | last = Willoughby | title = No agreement on Oath authentication | url = http://www.computerworld.com/s/article/99273/No_agreement_on_Oath_authentication | access-date = 2010-10-07 | archive-date = 2012-10-11 | archive-url = https://web.archive.org/web/20121011015244/http://www.computerworld.com/s/article/99273/No_agreement_on_Oath_authentication | url-status = dead }}</ref><ref>{{cite web | work = Computerworld | first = Burt | last = Kaliski | date = 2005-05-19 | title = Algorithm agility and OATH | url = http://www.computerworld.com/s/article/101788/Algorithm_agility_and_OATH | access-date = 2010-10-07 | archive-date = 2012-10-11 | archive-url = https://web.archive.org/web/20121011015258/http://www.computerworld.com/s/article/101788/Algorithm_agility_and_OATH | url-status = dead }}</ref> after IETF adopted HOTP as {{IETF RFC|4226}} in December 2005, various vendors started to produce HOTP-compatible tokens and/or whole authentication solutions.
According to the article "Road Map: Replacing Passwords with OTP Authentication"<ref name="gartnerotprm">{{cite web | work = Burton Group | year = 2010 | first = Mark | last = Diodati | title = Road Map: Replacing Passwords with OTP Authentication | url = http://www.burtongroup.com/Research/PublicDocument.aspx?cid=2107 | access-date = 2011-02-10 | archive-date = 2011-07-21 | archive-url = https://web.archive.org/web/20110721060420/http://www.burtongroup.com/Research/PublicDocument.aspx?cid=2107 | url-status = dead }}</ref> on strong authentication, published by Burton Group (a division of Gartner, Inc.) in 2010, "Gartner's expectation is that the hardware OTP form factor will continue to enjoy modest growth while smartphone OTPs will grow and become the default hardware platform over time."
== See also == * Initiative for Open Authentication * S/KEY * Time-based one-time password algorithm (TOTP)
== References == {{reflist}}
== External links == * [https://datatracker.ietf.org/doc/html/rfc4226 RFC 4226: HOTP: An HMAC-Based One-Time Password Algorithm] * [https://datatracker.ietf.org/doc/html/rfc6238 RFC 6238: TOTP: Time-Based One-Time Password Algorithm] * [https://datatracker.ietf.org/doc/html/rfc6287 RFC 6287: OCRA: OATH Challenge-Response Algorithm] * [https://openauthentication.org/ Initiative For Open Authentication] * [https://nbviewer.org/github/algorithmic-space/cryptoy/blob/master/rfc4226.ipynb Implementation of RFC 4226 - HOPT Algorithm] {{Webarchive|url=https://web.archive.org/web/20211216193608/https://nbviewer.org/github/algorithmic-space/cryptoy/blob/master/rfc4226.ipynb |date=2021-12-16 }} Step by step Python implementation in a Jupyter Notebook
Category:Internet protocols Category:Cryptographic algorithms Category:Computer access control protocols