RFC 6287

OCRA: OATH Challenge-Response Algorithm

πŸ“… published June 2011, from ietf

OCRA: OATH Challenge-Response Algorithm πŸ¦‹

Title block, the tea β˜•

  • RFC 6287, Category: Informational, ISSN 2070-1721
  • Published June 2011 by the Internet Engineering Task Force (IETF) 🌸
  • Authors: D. M'Raihi (Verisign, Inc.), J. Rydell (Portwise, Inc.), S. Bajaj (Symantec Corp.), S. Machani (Diversinet Corp.), and D. Naccache (Ecole Normale Superieure) πŸ‘‘
  • It doesn't obsolete or update anything. The title block lists nothing for either one 🫢

Table of Contents

   1. Introduction ....................................................3
   2. Notation and Terminology ........................................3
   3. Algorithm Requirements ..........................................3
   4. OCRA Background .................................................4
      4.1. HOTP Algorithm .............................................4
   5. Definition of OCRA ..............................................5
      5.1. DataInput Parameters .......................................5
      5.2. CryptoFunction .............................................7
   6. The OCRASuite ...................................................8
      6.1. Algorithm ..................................................9
      6.2. CryptoFunction .............................................9
      6.3. DataInput ..................................................9
      6.4. OCRASuite Examples ........................................10
   7. Algorithm Modes for Authentication .............................10
      7.1. One-Way Challenge-Response ................................11
      7.2. Mutual Challenge-Response .................................12
      7.3. Algorithm Modes for Signature .............................13
           7.3.1. Plain Signature ....................................13
           7.3.2. Signature with Server Authentication ...............14
   8. Security Considerations ........................................16
      8.1. Security Analysis of OCRA .................................16
      8.2. Implementation Considerations .............................17
   9. Conclusion .....................................................18
   10. Acknowledgements ..............................................18
   11. References ....................................................19
      11.1. Normative References .....................................19
      11.2. Informative References ...................................19
   Appendix A. Reference Implementation ..............................20
   Appendix B. Test Vectors Generation ...............................26
   Appendix C. Test Vectors ..........................................33
     C.1. One-Way Challenge Response .................................34
     C.2. Mutual Challenge-Response ..................................35
     C.3. Plain Signature ............................................37

Abstract ✨

okay so this doc describes a challenge-response authentication algorithm that the Initiative for Open Authentication (OATH) cooked up πŸ’… it's built on the HMAC-based One-Time Password (HOTP) algorithm, and it gives you one-way authentication, mutual authentication, and electronic signature capabilities. iconic πŸ”₯

Status of This Memo πŸ“œ

bestie, this doc is not an Internet Standards Track specification πŸ™ˆ it's published purely for informational purposes.

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). not all documents approved by the IESG are a candidate for any level of Internet Standard; see Section 2 of RFC 5741 πŸ’œ

Info about the current status of this document, any errata, and how to send feedback on it lives at http://www.rfc-editor.org/info/rfc6287 🧚

Copyright (c) 2011 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 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, since 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 they are provided without warranty as described in the Simplified BSD License. 🫢

1. Introduction ✨

so the Initiative for Open Authentication (OATH) [OATH] has spotted a bunch of use cases and scenarios that need an asynchronous variant, for people who don't want to keep an authentication system in sync πŸ¦‹ a commonly accepted way to do this is a challenge-response scheme.

This challenge-response mode of authentication is already widely adopted across the industry. Several vendors already ship software applications and hardware devices that implement challenge-response, but each one uses vendor-specific proprietary algorithms 😭 for the benefit of users, there's a real need for a standardized challenge-response algorithm. That allows multi-sourcing of token purchases and validation systems, which helps democratize strong authentication πŸ’–

Also, this specification describes how to create short symmetric key-based "electronic signatures". These signatures are variants of challenge-response mode, where the data to be signed becomes the challenge or is used to derive the challenge πŸŽ€ heads up that the terms 'electronic signature' and 'signature' are used interchangeably in this document πŸ’…

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 lays out the main requirements that drove the design of this algorithm πŸ“ a lot of emphasis went on flexibility and usability, within the constraints and specificity of the HMAC-based One-Time Password (HOTP) algorithm [RFC4226] and hardware token capabilities. main character energy πŸ‘‘

  • R1 - The algorithm MUST support challenge-response-based authentication. ✨
  • R2 - The algorithm MUST be capable of supporting symmetric key-based short electronic signatures. Basically, this is a variation of challenge-response where the challenge is derived from the data that needs to be signed πŸ”₯
  • R3 - The algorithm MUST be capable of supporting server authentication, whereby the user can verify that he/she is talking to a trusted server. Trust check, periodt πŸ’–
  • R4 - The algorithm SHOULD use HOTP [RFC4226] as a key building block. 🧚
  • R5 - The length and format of the input challenge SHOULD be configurable. πŸ¦‹
  • R6 - The output length and format of the generated response SHOULD be configurable. 🌈
  • R7 - The challenge MAY be generated with integrity checking (e.g., parity bits). This lets tokens with pin pads do simple error checking when the user enters the challenge value into a token πŸ™ˆ
  • R8 - There MUST be a unique secret (key) for each token/soft token that is shared between the token and the authentication server. The keys MUST be randomly generated or derived using a key derivation algorithm. no cap, this one's serious πŸ’œ
  • R9 - The algorithm MAY enable additional data attributes, such as a timestamp or session information, to be included in the computation. These data inputs MAY be used individually or all together. ⭐

4. OCRA Background 🌸

OATH introduced the HOTP algorithm as a first open, freely available building block for strengthening authentication for end-users in a variety of applications πŸŽ€ one-time passwords are super efficient at solving specific security issues, thanks to the dynamic nature of OTP computations. ✨

After carefully analyzing different use cases, OATH concluded that providing extensions to the HOTP algorithms was important πŸ¦‹ a very natural extension is a challenge mode for computing HOTP values based on random questions. Just as valuable is being able to do mutual authentication between two parties, or short-signature computation for authenticating transactions to improve the security of e-commerce applications πŸ’…

4.1. HOTP Algorithm 🧚

The HOTP algorithm, as defined in [RFC4226], is based on an increasing counter value and a static symmetric key known only to the prover and verifier parties.

As a reminder:

HOTP(K,C) = Truncate(HMAC-SHA1(K,C))

where Truncate represents the function that converts an HMAC-SHA-1 value into an HOTP value.

We refer the reader to [RFC4226] for the full description and further details on the rationale and security analysis of HOTP πŸ’œ

The present document describes the different variants based on similar constructions as HOTP. 🫢

5. Definition of OCRA πŸ’–

The OATH Challenge-Response Algorithm (OCRA) is a generalization of HOTP, with variable data inputs that are not solely based on an incremented counter and secret key values 🌈

The definition of OCRA requires a cryptographic function, a key K, and a set of DataInput parameters. This section first formally introduces OCRA, then introduces the definitions and default values recommended for all parameters. πŸŽ€

In a nutshell:

OCRA = CryptoFunction(K, DataInput)

where:

  • K: a shared secret key known to both parties πŸ”‘
  • DataInput: a structure that contains the concatenation of the various input data values, defined in detail in section 5.1 πŸ“
  • CryptoFunction: this is the function that performs the OCRA computation from the secret key K and the DataInput material 🧚

CryptoFunction is described in detail in Section 5.2 ✨

5.1. DataInput Parameters ✨

Okay bestie, this structure is basically one big byte array 🧡 made by gluing together the OCRASuite value from section 6 and all the other parameters, except the secret key K πŸ”. K stays out of the mix.

DataInput = {OCRASuite | 00 | C | Q | P | S | T} where:
  • OCRASuite is a value representing the suite of operations to compute an OCRA response
  • 00 is a byte value used as a separator
  • C is an unsigned 8-byte counter value processed high-order bit first, and MUST be synchronized between all parties; It loops around from "{Hex}0" to "{Hex}FFFFFFFFFFFFFFFF" and then starts over at "{Hex}0". Note that 'C' is optional for all OCRA modes described in this document. πŸ”
  • Q, mandatory, is a 128-byte list of (concatenated) challenge question(s) generated by the parties; if Q is less than 128 bytes, then it should be padded with zeroes to the right 🧩
  • P is a hash (SHA-1 [RFC3174], SHA-256 and SHA-512 [SHA2] are supported) value of PIN/password that is known to all parties during the execution of the algorithm; the length of P will depend on the hash function that is used πŸ”‘
  • S is a UTF-8 [RFC3629] encoded string of length up to 512 bytes that contains information about the current session; the length of S is defined in the OCRASuite string πŸ—‚οΈ
  • T is an 8-byte unsigned integer in big-endian order (i.e., network byte order) representing the number of time-steps (seconds, minutes, hours, or days depending on the specified granularity) since midnight UTC of January 1, 1970 [UT]. More specifically, if the OCRA computation includes a timestamp T, you should first convert your current local time to UTC time; you can then derive the UTC time in the proper format (i.e., seconds, minutes, hours, or days elapsed from epoch time); the size of the time-step is specified in the OCRASuite string as described in Section 6.3 ⏰

When you're computing a response, the concatenation order is always the following, no exceptions πŸ’…:

                                C |

             OTHER-PARTY-GENERATED-CHALLENGE-QUESTION |

                 YOUR-GENERATED-CHALLENGE-QUESTION |

                              P| S | T

If a value is empty (i.e., a certain input is not used in the computation) then the value is simply not represented in the string. So no empty placeholders, just skip it πŸ™ˆ

The counter on the token or client MUST be incremented every time a new computation is requested by the user. The server's counter value MUST only be incremented after a successful OCRA authentication. 🚨 This part is so important, the counters are the whole reason things stay in sync πŸ’œ

5.2. CryptoFunction 🧁

The default CryptoFunction is HOTP-SHA1-6, i.e., the default mode of computation for OCRA is HOTP with the default 6-digit dynamic truncation and a combination of DataInput values as the message to compute the HMAC-SHA1 digest. Iconic default, no notes πŸ’–

We denote t as the length in decimal digits of the truncation output. For instance, if t = 6, then the output of the truncation is a 6-digit (decimal) value. πŸ”’

We define the HOTP family of functions as an extension to HOTP:

  1. HOTP-H-t: these are the different possible truncated versions of HOTP, using the dynamic truncation method for extracting an HOTP value from the HMAC output
  2. We will denote HOTP-H-t as the realization of an HOTP function that uses an HMAC function with the hash function H, and the dynamic truncation as described in [RFC4226] to extract a t-digit value
  3. t=0 means that no truncation is performed and the full HMAC value is used for authentication purposes πŸ¦‹

We list the following preferred modes of computation, where * denotes the default CryptoFunction:

  • HOTP-SHA1-4: HOTP with SHA-1 as the hash function for HMAC and a dynamic truncation to a 4-digit value; this mode is not recommended in the general case, but it can be useful when a very short authentication code is needed by an application πŸ™ƒ
  • HOTP-SHA1-6: HOTP with SHA-1 as the hash function for HMAC and a dynamic truncation to a 6-digit value 🌸
  • HOTP-SHA1-8: HOTP with SHA-1 as the hash function for HMAC and a dynamic truncation to an 8-digit value ✨
  • HOTP-SHA256-6: HOTP with SHA-256 as the hash function for HMAC and a dynamic truncation to a 6-digit value 🌈
  • HOTP-SHA512-6: HOTP with SHA-512 as the hash function for HMAC and a dynamic truncation to a 6-digit value πŸ‘‘

This table summarizes all possible values for the CryptoFunction πŸ“‹:

  +---------------+--------------------+-------------------------+
  |      Name     | HMAC Function Used |  Size of Truncation (t) |
  +---------------+--------------------+-------------------------+
  |  HOTP-SHA1-t  |      HMAC-SHA1     | 0 (no truncation), 4-10 |
  | HOTP-SHA256-t |     HMAC-SHA256    | 0 (no truncation), 4-10 |
  | HOTP-SHA512-t |     HMAC-SHA512    | 0 (no truncation), 4-10 |
  +---------------+--------------------+-------------------------+

                    Table 1: CryptoFunction Table

6. The OCRASuite πŸŽ€

An OCRASuite value is a text string that captures one mode of operation for OCRA, completely specifying the various options for that computation. It's basically the full outfit description for one computation πŸ‘—. An OCRASuite value is represented as follows:

               <Algorithm>:<CryptoFunction>:<DataInput>

The OCRASuite value is the concatenation of three sub-components that are described below. Some example OCRASuite strings are described in Section 6.4 πŸ§ƒ.

The client and server need to agree on one or two values of OCRASuite. These values may be agreed upon at the time of token provisioning or, for more sophisticated client-server interactions, these values may be negotiated for every transaction 🀝.

The provisioning of OCRA keys and related metadata such as OCRASuite is out of scope for this document. [RFC6030] specifies one key container specification that facilitates provisioning of such data between the client and the server πŸ“¦.

Note that for Mutual Challenge-Response or Signature with Server Authentication modes, the client and server will need to agree on two values of OCRASuite -- one for server computation and another for client computation πŸ‘―.

6.1. Algorithm 🧠

Description: Indicates the version of OCRA.

Values: OCRA-v where v represents the version number (e.g., 1, 2). This document specifies version 1 of OCRA.

6.2. CryptoFunction πŸ”

Description: Indicates the function used to compute OCRA values.

Values: Permitted values are described in Section 5.2.

6.3. DataInput πŸ“

Description: This component of the OCRASuite string captures the list of valid inputs for that computation; [] indicates a value is optional:

[C] | QFxx | [PH | Snnn | TG] : Challenge-Response computation

[C] | QFxx | [PH | TG] : Plain Signature computation

Each input that is used for the computation is represented by a single letter (except Q), and they are separated by a hyphen. Cute and tidy πŸŽ€.

The input for challenge is further qualified by the formats supported by the client for challenge question(s). Supported values can be:

                 +------------------+-------------------+
                 |    Format (F)    | Up to Length (xx) |
                 +------------------+-------------------+
                 | A (alphanumeric) |       04-64       |
                 |    N (numeric)   |       04-64       |
                 |  H (hexadecimal) |       04-64       |
                 +------------------+-------------------+

                      Table 2: Challenge Format Table

The default challenge format is N08, numeric and up to 8 digits. πŸ”’

The input for P is further qualified by the hash function used for the PIN/password. Supported values for hash function can be:

Hash function (H) - SHA1, SHA256, SHA512.

The default hash function for P is SHA1. πŸ”‘

The input for S is further qualified by the length of the session data in bytes. The client and server could agree to any length but the typical values are:

Length (nnn) - 064, 128, 256, and 512.

The default length is 064 bytes. πŸ—‚οΈ

The input for timestamps is further qualified by G, size of the time-step. G can be specified in number of seconds, minutes, or hours ⏱️:

           +--------------------+------------------------------+
           | Time-Step Size (G) |           Examples           |
           +--------------------+------------------------------+
           |       [1-59]S      | number of seconds, e.g., 20S |
           |       [1-59]M      |  number of minutes, e.g., 5M |
           |       [0-48]H      |  number of hours, e.g., 24H  |
           +--------------------+------------------------------+

                       Table 3: Time-step Size Table

Default value for G is 1M, i.e., time-step size is one minute and the T represents the number of minutes since epoch time [UT]. Main character energy 🌟.

6.4. OCRASuite Examples πŸ’Œ

Here are some examples of OCRASuite strings, bestie 🫢:

  • "OCRA-1:HOTP-SHA512-8:C-QN08-PSHA1" means version 1 of OCRA with HMAC-SHA512 function, truncated to an 8-digit value, using the counter, a random challenge, and a SHA1 digest of the PIN/password as parameters. It also indicates that the client supports only numeric challenge up to 8 digits in length πŸ”₯
  • "OCRA-1:HOTP-SHA256-6:QA10-T1M" means version 1 of OCRA with HMAC-SHA256 function, truncated to a 6-digit value, using a random alphanumeric challenge up to 10 characters in length and a timestamp in number of minutes since epoch time πŸ¦‹
  • "OCRA-1:HOTP-SHA1-4:QH8-S512" means version 1 of OCRA with HMAC-SHA1 function, truncated to a 4-digit value, using a random hexadecimal challenge up to 8 nibbles and a session value of 512 bytes 🧚

7. Algorithm Modes for Authentication πŸ”βœ¨

This section describes the typical modes in which the above defined computation can be used for authentication. Okay, the fun part is coming up, so stay with me πŸ’œ.

7.1. One-Way Challenge-Response

okay so a challenge-response is basically a security move where the verifier asks the prover a question (the challenge), and the prover has to come back with a correct answer (the response) to get authenticated πŸ”βœ¨

so for one-way challenge-response, the verifier sends over a challenge value (usually randomly generated 🎲), the prover uses that challenge in the computation like we talked about above, and then the prover sends the response back so they can be authenticated πŸ’–

in this mode, the typical data inputs look like this:

  • C - Counter, optional.
  • Q - Challenge question, mandatory, supplied by the verifier.
  • P - Hashed version of PIN/password, optional.
  • S - Session information, optional.
  • T - Timestamp, optional.

this diagram shows the message exchange between the client (prover) and the server (verifier) for a one-way challenge-response. it's giving very clean back-and-forth energy πŸ¦‹

it's assumed that the client and server already share a pre-shared key K that gets used in the computation πŸ—οΈ

           CLIENT                                   SERVER
          (PROVER)                                 VERIFIER)
             |                                        |
             |   Verifier sends challenge to prover   |
             |   Challenge = Q                        |
             |<---------------------------------------|
             |                                        |
             |   Prover Computes Response             |
             |   R = OCRA(K, {[C] | Q | [P | S | T]}) |
             |   Prover sends Response = R            |
             |--------------------------------------->|
             |                                        |
             |  Verifier Validates Response           |
             |  If Response is valid, Server sends OK |
             |  If Response is not,  Server sends NOK |
             |<---------------------------------------|
             |                                        |

7.2. Mutual Challenge-Response

this one is a glow-up of the one-way version where the client and server both authenticate each other 🫢🌸

here's how it goes: the client starts by sending a random client-challenge to the server. then the server computes the server-response and sends it back to the client along with a server-challenge πŸŽ€

the client checks the server-response first so it knows it's actually talking to a legit server (no sus servers allowed πŸ™…β€β™€οΈ). after that, the client computes the client-response and sends it over to authenticate itself. the server verifies that client-response and that finishes off the two-way authentication πŸ‘‘

in this mode there are two computations: the client-response and the server-response. there are two separate challenge questions, one generated by each party. we call these challenge questions Q1 and Q2 🧚

typical data inputs for the server-response computation are:

  • C - Counter, optional.
  • QC - Challenge question, mandatory, supplied by the client.
  • QS - Challenge question, mandatory, supplied by the server.
  • S - Session information, optional.
  • T - Timestamp, optional.

typical data inputs for the client-response computation are:

  • C - Counter, optional.
  • QS - Challenge question, mandatory, supplied by the server.
  • QC - Challenge question, mandatory, supplied by the client.
  • P - Hashed version of PIN/password, optional.
  • S - Session information, optional.
  • T - Timestamp, optional.

the following diagram shows the messages going back and forth between the client and server for a full two-way mutual challenge-response. it's so organized it's giving me a headache in the best way 🀩

it's assumed that the client and server have a pre-shared key K (or a pair of keys if they're using dual-key mode of computation) that gets used in the computation πŸ”‘

      CLIENT                                             SERVER
     (PROVER)                                          (VERIFIER)
        |                                                  |
        |   1. Client sends client-challenge               |
        |   QC = Client-challenge                          |
        |------------------------------------------------->|
        |                                                  |
        |   2. Server computes server-response             |
        |      and sends server-challenge                  |
        |   RS = OCRA(K, [C] | QC | QS | [S | T])          |
        |   QS = Server-challenge                          |
        |   Response = RS, QS                              |
        |<-------------------------------------------------|
        |                                                  |
        |   3. Client verifies server-response             |
        |      and computes client-response                |
        |   OCRA(K, [C] | QC | QS | [S | T]) != RS -> STOP |
        |   RC = OCRA(K, [C] | QS | QC | [P | S | T])      |
        |   Response = RC                                  |
        |------------------------------------------------->|
        |                                                  |
        |   4. Server verifies client-response             |
        |   OCRA(K, [C] | QS | QC | [P|S|T]) != RC -> STOP |
        |   Response = OK                                  |
        |<-------------------------------------------------|
        |                                                  |

7.3. Algorithm Modes for Signature

okay now let's talk about the modes where this whole computation gets used for electronic signatures βœοΈπŸ’… here are the typical ones we're covering πŸ¦‹

7.3.1. Plain Signature

so in plain signature mode, the server sends a signature-challenge value to the client (the signer) πŸ“ the signature-challenge is either the data you want signed, or something derived from that data using a hash function, for example πŸ”₯

the client uses the signature-challenge in the computation like we described above. then the client sends the signature value (the response) back to the server to authenticate ✨

in this mode, the data inputs are:

  • C - Counter, optional.
  • QS - Signature-challenge, mandatory, supplied by the server.
  • P - Hashed version of PIN/password, optional.
  • T - Timestamp, optional.

the picture below shows the messages exchanged between the client (prover) and the server (verifier) for a plain signature operation πŸ–ΌοΈ

it's assumed that the client and server have a pre-shared key K that gets used in the computation πŸ—οΈ

         CLIENT                                     SERVER
        (PROVER)                                  (VERIFIER)
           |                                           |
           |    Verifier sends signature-challenge     |
           |    Challenge = QS                         |
           |<------------------------------------------|
           |                                           |
           |    Client Computes Response               |
           |    SIGN = OCRA(K, [C] | QS | [P | T])     |
           |    Response = SIGN                        |
           |------------------------------------------>|
           |                                           |
           |    Verifier Validates Response            |
           |    Response = OK                          |
           |<------------------------------------------|
           |                                           |

7.3.2. Signature with Server Authentication

this mode is basically plain signature mode with a glow-up πŸ’Ž the client can authenticate the server first before it generates an electronic signature, so nobody's signing for a fake server πŸ™ˆ

to use this one, the client starts by sending a random client-challenge to the server. the server computes the server-response and sends it back to the client along with a signature-challenge πŸŽ€

the client checks the server-response first to make sure it's talking to a valid server. only after that does it compute the signature and send it over πŸ’…

in this mode there are two computations: the client-signature and the server-response.

typical data inputs for the server-response computation are:

  • C - Counter, optional.
  • QC - Challenge question, mandatory, supplied by the client.
  • QS - Signature-challenge, mandatory, supplied by the server.
  • T - Timestamp, optional.

typical data inputs for the client-signature computation are:

  • C - Counter, optional.
  • QC - Challenge question, mandatory, supplied by the client.
  • QS - Signature-challenge, mandatory, supplied by the server.
  • P - Hashed version of PIN/password, optional.
  • T - Timestamp, optional.

the diagram below shows the messages exchanged between the client and server for a signature with server authentication transaction. it's the full package 🌈

it's assumed that the client and server have a pre-shared key K (or a pair of keys if using dual-key mode of computation) that gets used in the computation πŸ”‘

      CLIENT                                              SERVER
     (PROVER)                                            VERIFIER)
        |                                                   |
        |    1. Client sends client-challenge               |
        |    QC = Client-challenge                          |
        |-------------------------------------------------->|
        |                                                   |
        |    2. Server computes server-response             |
        |       and sends signature-challenge               |
        |    RS = OCRA(K, [C] | QC | QS | [T])              |
        |    QS = signature-challenge                       |
        |    Response = RS, QS                              |
        |<--------------------------------------------------|
        |                                                   |
        |    3. Client verifies server-response             |
        |       and computes signature                      |
        |    OCRA(K, [C] | QC | QS | [T]) != RS -> STOP     |
        |    SIGN = OCRA( K, [C] | QS | QC | [P | T])       |
        |    Response = SIGN                                |
        |-------------------------------------------------->|
        |                                                   |
        |    4. Server verifies Signature                   |
        |    OCRA(K, [C] | QS | QC | [P|T]) != SIGN -> STOP |
        |    Response = OK                                  |
        |<--------------------------------------------------|
        |                                                   |

8. Security Considerations πŸ›‘οΈβš οΈ

okay bestie, this part is serious, so let's get into it πŸ₯Ί any algorithm is only as secure as the applications and authentication protocols that implement it πŸ™ˆ so this section talks about the critical security requirements that our algorithm choice puts on the authentication protocol and the validation software. no shortcuts πŸ’€

8.1. Security Analysis of OCRA

the security and strength of this algorithm depend on the properties of the building block underneath it, HOTP. HOTP is built on HMAC [RFC2104] using SHA-1 [RFC3174] (or SHA-256 or SHA-512 [SHA2]) as the hash function 🧩

the conclusion of the security analysis in [RFC4226] is that, for all practical purposes, the outputs of the dynamic truncation on distinct counter inputs are uniformly and independently distributed strings. ✨ that's a big deal, iykyk

the analysis also shows that the best possible attack against the HOTP function is the brute force attack 😭

8.2. Implementation Considerations ✨

okay so this is the implementation checklist, bestie πŸŽ€ and it's giving "do these or your system gets weird." Here we go πŸ’…

IC1 - In the authentication mode, the client MUST support two-factor authentication πŸ”. That means checking something you know (a secret code like a password, pass phrase, or PIN πŸ™ˆ) and something you have (a token πŸͺ™). The secret code is only known by the user, and they usually type it in with the Response value for authentication. Or, instead of sending the something-you-know to the server, the client can use a hash of the password or PIN inside the computation itself, so two-factor happens implicitly. Iconic πŸ‘‘

IC2 - Keys SHOULD be the same length as the CryptoFunction output so everyone plays nicely together 🫢

IC3 - Keys SHOULD be picked at random, or with a cryptographically strong pseudo-random generator that's been properly seeded with a random value 🎲. We RECOMMEND following [RFC4086] for all pseudo-random and random generations, no cap 🧠. The pseudo-random numbers used for key generation SHOULD pass the randomness test in [CN] βœ…

IC4 - Challenge questions SHOULD be 20-byte values, and they MUST be at least t-byte values, where t is the digit-length of the OCRA truncation output 🌸

IC5 - On the client side, the keys SHOULD live in a tamper-resistant device or be securely built into a software app πŸ”’. Also, putting the keys in a hardware device gives you extra mobility for the whole auth system, which is lowkey a big win πŸ¦‹

IC6 - All communication SHOULD happen over a secure channel, like SSL/TLS [RFC5246] or IPsec connections πŸ›‘οΈ

IC7 - OCRA in mutual authentication mode or in signature with server authentication mode MAY use dual-key mode πŸ—οΈβœ¨. That means there are two keys shared between the client and the server. One key makes the server response on the server side and checks it on the client side. The other key makes the response or signature on the client side and checks it on the server side. Two keys, double the vibes πŸ’œ

IC8 - We recommend that implementations MAY use the session information, S, as an extra input in the computation 🧚. For example, S could be the session identifier from the TLS session. This helps guard against certain man-in-the-middle attacks πŸ™…β€β™€οΈ. BUT, it adds a dependency: the prover needs access to the session identifier to compute the response, and the verifier needs it too to check the response 🫠. [RFC5056] has a relevant discussion about using Channel Bindings to Secure Channels, so go read that if you're curious πŸ“š

IC9 - In signature mode, if the counter or time (both optional elements) aren't used in the computation, there might be a risk of replay attacks ⚠️. Implementers should think carefully about this in light of their application requirements and security guidelines πŸ€“. The server SHOULD also, whenever possible, give the client (if it's able) a way to verify that the signature challenge is valid βœ…

IC10 - We also RECOMMEND storing the keys securely in the validation system πŸ”. Specifically, encrypt them with tamper-resistant hardware encryption and only expose them when you actually need to. For example, decrypt the key when you need to verify an OCRA response, then re-encrypt it right away so it sits in RAM for as short a time as possible πŸ’€. The key store MUST be in a secure area, to avoid direct attacks on the validation system and secrets database as much as possible 🏰. Especially, access to the key material should be limited to only the programs and processes the validation system needs 🫢

9. Conclusion 🌈

okay wrap-up time πŸŽ€ This document introduced several variants of HOTP for challenge-response-based authentication and short signature-like computations ✨

The OCRASuite makes it super easy to integrate and support different flavors inside an authentication and validation system πŸ’…

And finally, OCRA should enable mutual authentication in both connected and off-line modes, with support for different response sizes and modes of operation πŸ¦‹ Literally the whole vibe ✨


10. Acknowledgements 🫢

Huge thanks to Jeff Burstein, Shuh Chang, Oanh Hoang, Philip Hoyer, Jon Martinsson, Frederik Mennes, Mingliang Pei, Jonathan Tuliani, Stu Vaeth, Enrique Rodriguez, and Robert Zuccherato πŸ’– for their comments and suggestions that made this document better 🌸


11. References πŸ“š

11.1. Normative References

[RFC2104]  Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-
           Hashing for Message Authentication", RFC 2104,
           February 1997.

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC3174]  Eastlake, D. and P. Jones, "US Secure Hash Algorithm 1
           (SHA1)", RFC 3174, September 2001.

[RFC3629]  Yergeau, F., "UTF-8, a transformation format of ISO
           10646", STD 63, RFC 3629, November 2003.

[RFC4086]  Eastlake, D., Schiller, J., and S. Crocker, "Randomness
           Requirements for Security", BCP 106, RFC 4086, June 2005.

[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.

[SHA2]     NIST, "FIPS PUB 180-3: Secure Hash Standard (SHS)",
           October 2008, <http://csrc.nist.gov/publications/fips/
           fips180-3/fips180-3_final.pdf>.

11.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>.

[OATH]     Initiative for Open Authentication, "OATH Vision",
           <http://www.openauthentication.org/about>.

[RFC5056]  Williams, N., "On the Use of Channel Bindings to Secure
           Channels", RFC 5056, November 2007.

[RFC5246]  Dierks, T. and E. Rescorla, "The Transport Layer Security
           (TLS) Protocol Version 1.2", RFC 5246, August 2008.

[RFC6030]  Hoyer, P., Pei, M., and S. Machani, "Portable Symmetric
           Key Container (PSKC)", RFC 6030, October 2010.

[UT]       Wikipedia, "Unix time",
           <http://en.wikipedia.org/wiki/Unix_time>.

Appendix A. Reference Implementation πŸ’»βœ¨

okay bestie, here's the reference implementation 🫢 it's a Java OCRA class that builds the message, runs HMAC, and does the truncation. the copyright header is kept exactly as written πŸ’œ

/**
   Copyright (c) 2011 IETF Trust and the persons identified as
   authors of the code. All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, is permitted pursuant to, and subject to the license
   terms contained in, the Simplified BSD License set forth in Section
   4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
   (http://trustee.ietf.org/license-info).
 */

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;

/**
 * This an example implementation of OCRA.
 * Visit www.openauthentication.org for more information.
 *
 * @author Johan Rydell, PortWise
 */
public class OCRA {

    private OCRA() {}

    /**
     * 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.
     */

    private static byte[] hmac_sha1(String crypto,
                     byte[] keyBytes, byte[] text){
        Mac hmac = null;
        try {
            hmac = Mac.getInstance(crypto);
            SecretKeySpec macKey =
                new SecretKeySpec(keyBytes, "RAW");

            hmac.init(macKey);
            return hmac.doFinal(text);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    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 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];
        System.arraycopy(bArray, 1, ret, 0, ret.length);
        return ret;
    }


    /**
     * This method generates an OCRA HOTP value for the given
     * set of parameters.
     *
     * @param ocraSuite    the OCRA Suite
     * @param key          the shared secret, HEX encoded
     * @param counter      the counter that changes on a per use
     *                     basis, HEX encoded
     * @param question     the challenge question, HEX encoded
     * @param password     a password that can be used, HEX encoded
     * @param sessionInformation Static information that identifies
     *                     the current session, Hex encoded
     * @param timeStamp    a value that reflects a time
     *
     * @return A numeric String in base 10 that includes
     * {@link truncationDigits} digits
     */
    static public String generateOCRA(String ocraSuite,
            String key,
            String counter,
            String question,
            String password,
            String sessionInformation,
            String timeStamp){

        int codeDigits = 0;
        String crypto = "";
        String result = null;
        int ocraSuiteLength = (ocraSuite.getBytes()).length;
        int counterLength = 0;
        int questionLength = 0;
        int passwordLength = 0;
        int sessionInformationLength = 0;
        int timeStampLength = 0;

        // The OCRASuites components
        String CryptoFunction = ocraSuite.split(":")[1];
        String DataInput = ocraSuite.split(":")[2];


        if(CryptoFunction.toLowerCase().indexOf("sha1") > 1)
            crypto = "HmacSHA1";
        if(CryptoFunction.toLowerCase().indexOf("sha256") > 1)
            crypto = "HmacSHA256";
        if(CryptoFunction.toLowerCase().indexOf("sha512") > 1)
            crypto = "HmacSHA512";

        // How many digits should we return
        codeDigits = Integer.decode(CryptoFunction.substring(
                CryptoFunction.lastIndexOf("-")+1));

        // The size of the byte array message to be encrypted
        // Counter
        if(DataInput.toLowerCase().startsWith("c")) {
            // Fix the length of the HEX string
            while(counter.length() < 16)
                counter = "0" + counter;
            counterLength=8;
        }
        // Question - always 128 bytes
        if(DataInput.toLowerCase().startsWith("q") ||
                (DataInput.toLowerCase().indexOf("-q") >= 0)) {
            while(question.length() < 256)
                question = question + "0";

            questionLength=128;
        }

        // Password - sha1
        if(DataInput.toLowerCase().indexOf("psha1") > 1){
            while(password.length() < 40)
                password = "0" + password;
            passwordLength=20;
        }

        // Password - sha256
        if(DataInput.toLowerCase().indexOf("psha256") > 1){
            while(password.length() < 64)
                password = "0" + password;
            passwordLength=32;
        }

        // Password - sha512
        if(DataInput.toLowerCase().indexOf("psha512") > 1){
            while(password.length() < 128)
                password = "0" + password;
            passwordLength=64;
        }

        // sessionInformation - s064
        if(DataInput.toLowerCase().indexOf("s064") > 1){
            while(sessionInformation.length() < 128)
                sessionInformation = "0" + sessionInformation;
            sessionInformationLength=64;
        }

        // sessionInformation - s128
        if(DataInput.toLowerCase().indexOf("s128") > 1){
            while(sessionInformation.length() < 256)
                sessionInformation = "0" + sessionInformation;
            sessionInformationLength=128;
        }

        // sessionInformation - s256
        if(DataInput.toLowerCase().indexOf("s256") > 1){
            while(sessionInformation.length() < 512)
                sessionInformation = "0" + sessionInformation;
            sessionInformationLength=256;
        }

        // sessionInformation - s512
        if(DataInput.toLowerCase().indexOf("s512") > 1){
            while(sessionInformation.length() < 1024)

                sessionInformation = "0" + sessionInformation;
            sessionInformationLength=512;
        }

        // TimeStamp
        if(DataInput.toLowerCase().startsWith("t") ||
                (DataInput.toLowerCase().indexOf("-t") > 1)){
            while(timeStamp.length() < 16)
                timeStamp = "0" + timeStamp;
            timeStampLength=8;
        }

        // Remember to add "1" for the "00" byte delimiter
        byte[] msg = new byte[ocraSuiteLength +
                      counterLength +
                      questionLength +
                      passwordLength +
                      sessionInformationLength +
                      timeStampLength +
                      1];


        // Put the bytes of "ocraSuite" parameters into the message
        byte[] bArray = ocraSuite.getBytes();
        System.arraycopy(bArray, 0, msg, 0, bArray.length);

        // Delimiter
        msg[bArray.length] = 0x00;

        // Put the bytes of "Counter" to the message
        // Input is HEX encoded
        if(counterLength > 0 ){
            bArray = hexStr2Bytes(counter);
            System.arraycopy(bArray, 0, msg, ocraSuiteLength + 1,
                    bArray.length);
        }


        // Put the bytes of "question" to the message
        // Input is text encoded
        if(questionLength > 0 ){
            bArray = hexStr2Bytes(question);
            System.arraycopy(bArray, 0, msg, ocraSuiteLength + 1 +
                    counterLength, bArray.length);
        }

        // Put the bytes of "password" to the message
        // Input is HEX encoded
        if(passwordLength > 0){
            bArray = hexStr2Bytes(password);
            System.arraycopy(bArray, 0, msg, ocraSuiteLength + 1 +
                    counterLength +    questionLength, bArray.length);

        }

        // Put the bytes of "sessionInformation" to the message
        // Input is text encoded
        if(sessionInformationLength > 0 ){
            bArray = hexStr2Bytes(sessionInformation);
            System.arraycopy(bArray, 0, msg, ocraSuiteLength + 1 +
                    counterLength +     questionLength +
                    passwordLength, bArray.length);
        }

        // Put the bytes of "time" to the message
        // Input is text value of minutes
        if(timeStampLength > 0){
            bArray = hexStr2Bytes(timeStamp);
            System.arraycopy(bArray, 0, msg, ocraSuiteLength + 1 +
                    counterLength + questionLength +
                    passwordLength + sessionInformationLength,
                    bArray.length);
        }

        bArray = hexStr2Bytes(key);

        byte[] 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;
    }
}

Appendix B. Test Vectors Generation πŸ§ͺ🌈

ngl this one is the test vector generator πŸ₯Ή it's a Java TestOCRA class with an asHex helper and a main that sets up the inputs, so you can check your own build against the RFC's numbers. the copyright header is the same one from Appendix A πŸ’œ

/**
   Copyright (c) 2011 IETF Trust and the persons identified as
   authors of the code. All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, is permitted pursuant to, and subject to the license
   terms contained in, the Simplified BSD License set forth in Section
   4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
   (http://trustee.ietf.org/license-info).
 */

import java.math.BigInteger;
import java.util.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class TestOCRA {

public static String asHex (byte buf[]) {
    StringBuffer strbuf = new StringBuffer(buf.length * 2);
    int i;

    for (i = 0; i < buf.length; i++) {
        if (((int) buf[i] & 0xff) < 0x10)
            strbuf.append("0");
        strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
    }
    return strbuf.toString();
}

/**
 * @param args
 */
public static void main(String[] args) {

    String ocra = "";
    String seed = "";
    String ocraSuite = "";
    String counter = "";
    String password = "";
    String sessionInformation = "";
    String question = "";
    String qHex = "";
    String timeStamp = "";

    // PASS1234 is SHA1 hash of "1234"
    String PASS1234 = "7110eda4d09e062aa5e4a390b0a572ac0d2c0220";

Okay bestie, the test vector code keeps going πŸ§šπŸ’–

          System.out.println(
                      "Key: Standard 64Byte  Q(Signature challenge): "
                      + question);
              System.out.println("   T: "
                      + timeStamp.toUpperCase() + "  OCRA: "
                      + ocra);
          }

      }catch (Exception e){
                System.out.println("Error : " + e);
      }
  }
  }
  <CODE ENDS>

Appendix C. Test Vectors πŸ§ͺ✨

Bestie, this is the goodie bag! 🎁 These are the test values you can use to check that your OCRA implementation plays nicely with everyone else's during interoperability testing πŸ’…

Here are the keys we'll be using. The Standard 20Byte key: value is:

3132333435363738393031323334353637383930

The Standard 32Byte key: value is:

3132333435363738393031323334353637383930313233343536373839303132

The Standard 64Byte key: value is:

313233343536373839303132333435363738393031323334353637383930313233343
53637383930313233343536373839303132333435363738393031323334

And the PIN (1234) SHA1 hash value: is:

7110eda4d09e062aa5e4a390b0a572ac0d2c0220

C.1. One-Way Challenge Response 🌸

Okay so this is the one-way challenge-response set, and the first table is the Standard 20Byte key with a bunch of Q values. Each row pairs a challenge with the OCRA value it should produce πŸ¦‹

                +-----------------+----------+------------+
                |       Key       |     Q    | OCRA Value |
                +-----------------+----------+------------+
                | Standard 20Byte | 00000000 |   237653   |
                | Standard 20Byte | 11111111 |   243178   |
                | Standard 20Byte | 22222222 |   653583   |
                | Standard 20Byte | 33333333 |   740991   |
                | Standard 20Byte | 44444444 |   608993   |
                | Standard 20Byte | 55555555 |   388898   |
                | Standard 20Byte | 66666666 |   816933   |
                | Standard 20Byte | 77777777 |   224598   |
                | Standard 20Byte | 88888888 |   750600   |
                | Standard 20Byte | 99999999 |   294470   |
                +-----------------+----------+------------+

This set uses the suite OCRA-1:HOTP-SHA1-6:QN08 πŸ’–

                          OCRA-1:HOTP-SHA1-6:QN08

Next up is the Standard 32Byte key with a counter C in the mix πŸ”₯

              +-----------------+---+----------+------------+
              |       Key       | C |     Q    | OCRA Value |
              +-----------------+---+----------+------------+
              | Standard 32Byte | 0 | 12345678 |  65347737  |
              | Standard 32Byte | 1 | 12345678 |  86775851  |
              | Standard 32Byte | 2 | 12345678 |  78192410  |
              | Standard 32Byte | 3 | 12345678 |  71565254  |
              | Standard 32Byte | 4 | 12345678 |  10104329  |
              | Standard 32Byte | 5 | 12345678 |  65983500  |
              | Standard 32Byte | 6 | 12345678 |  70069104  |
              | Standard 32Byte | 7 | 12345678 |  91771096  |
              | Standard 32Byte | 8 | 12345678 |  75011558  |
              | Standard 32Byte | 9 | 12345678 |  08522129  |
              +-----------------+---+----------+------------+

That one runs on OCRA-1:HOTP-SHA1-6:QN08... wait, no, the suite for this table is the one below πŸ™ˆ Here it is:

                     OCRA-1:HOTP-SHA256-8:C-QN08-PSHA1

Now the Standard 32Byte key with a fresh set of Q values, same vibe as before ✨

                +-----------------+----------+------------+
                |       Key       |     Q    | OCRA Value |
                +-----------------+----------+------------+
                | Standard 32Byte | 00000000 |  83238735  |
                | Standard 32Byte | 11111111 |  01501458  |
                | Standard 32Byte | 22222222 |  17957585  |
                | Standard 32Byte | 33333333 |  86776967  |
                | Standard 32Byte | 44444444 |  86807031  |
                +-----------------+----------+------------+

And its suite:

                      OCRA-1:HOTP-SHA256-8:QN08-PSHA1

Next, the Standard 64Byte key goes full counter-mode with C values 00000 to 00009 🌈

            +-----------------+-------+----------+------------+
            |       Key       |   C   |     Q    | OCRA Value |
            +-----------------+-------+----------+------------+
            | Standard 64Byte | 00000 | 00000000 |  07016083  |
            | Standard 64Byte | 00001 | 11111111 |  63947962  |
            | Standard 64Byte | 00002 | 22222222 |  70123924  |
            | Standard 64Byte | 00003 | 33333333 |  25341727  |
            | Standard 64Byte | 00004 | 44444444 |  33203315  |
            | Standard 64Byte | 00005 | 55555555 |  34205738  |
            | Standard 64Byte | 00006 | 66666666 |  44343969  |
            | Standard 64Byte | 00007 | 77777777 |  51946085  |
            | Standard 64Byte | 00008 | 88888888 |  20403879  |
            | Standard 64Byte | 00009 | 99999999 |  31409299  |
            +-----------------+-------+----------+------------+

Suite time:

                        OCRA-1:HOTP-SHA512-8:C-QN08

The last one in this section adds a T (time) column, with the Standard 64Byte key and T value 132d0b6 πŸ•°οΈπŸ’œ

           +-----------------+----------+---------+------------+
           |       Key       |     Q    |    T    | OCRA Value |
           +-----------------+----------+---------+------------+
           | Standard 64Byte | 00000000 | 132d0b6 |  95209754  |
           | Standard 64Byte | 11111111 | 132d0b6 |  55907591  |
           | Standard 64Byte | 22222222 | 132d0b6 |  22048402  |
           | Standard 64Byte | 33333333 | 132d0b6 |  24218844  |
           | Standard 64Byte | 44444444 | 132d0b6 |  36209546  |
           +-----------------+----------+---------+------------+

And the suite for that one:

                       OCRA-1:HOTP-SHA512-8:QN08-T1M

C.2. Mutual Challenge-Response πŸ€πŸ’•

Mutual challenge-response means both sides compute, so the server and client each get their own suite lines 🫢

The server computation uses this suite:

OCRASuite (server computation) = OCRA-1:HOTP-SHA256-8:QA08

And the client computation uses this one:

OCRASuite (client computation) = OCRA-1:HOTP-SHA256-8:QA08

First, the client-side challenges (the CLI values) with the Standard 32Byte key πŸ’…

            +-----------------+------------------+------------+
            |       Key       |         Q        | OCRA Value |
            +-----------------+------------------+------------+
            | Standard 32Byte | CLI22220SRV11110 |  28247970  |
            | Standard 32Byte | CLI22221SRV11111 |  01984843  |
            | Standard 32Byte | CLI22222SRV11112 |  65387857  |
            | Standard 32Byte | CLI22223SRV11113 |  03351211  |
            | Standard 32Byte | CLI22224SRV11114 |  83412541  |
            +-----------------+------------------+------------+

Then the server computes with this label:

                    Server -- OCRA-1:HOTP-SHA256-8:QA08

Now the server-side challenges (the SRV values) πŸ‘‘

            +-----------------+------------------+------------+
            |       Key       |         Q        | OCRA Value |
            +-----------------+------------------+------------+
            | Standard 32Byte | SRV11110CLI22220 |  15510767  |
            | Standard 32Byte | SRV11111CLI22221 |  90175646  |
            | Standard 32Byte | SRV11112CLI22222 |  33777207  |
            | Standard 32Byte | SRV11113CLI22223 |  95285278  |
            | Standard 32Byte | SRV11114CLI22224 |  28934924  |
            +-----------------+------------------+------------+

And the client's label for that one:

                    Client -- OCRA-1:HOTP-SHA256-8:QA08

Now the second mutual set uses SHA512, and the suites are different for server and client. Look at them! πŸ‘€

OCRASuite (server computation) = OCRA-1:HOTP-SHA512-8:QA08
OCRASuite (client computation) = OCRA-1:HOTP-SHA512-8:QA08-PSHA1

Client-side CLI challenges with the Standard 64Byte key 🌸

            +-----------------+------------------+------------+
            |       Key       |         Q        | OCRA Value |
            +-----------------+------------------+------------+
            | Standard 64Byte | CLI22220SRV11110 |  79496648  |
            | Standard 64Byte | CLI22221SRV11111 |  76831980  |
            | Standard 64Byte | CLI22222SRV11112 |  12250499  |
            | Standard 64Byte | CLI22223SRV11113 |  90856481  |
            | Standard 64Byte | CLI22224SRV11114 |  12761449  |
            +-----------------+------------------+------------+

The server label for this set:

                    Server -- OCRA-1:HOTP-SHA512-8:QA08

Server-side SRV challenges, same key:

            +-----------------+------------------+------------+
            |       Key       |         Q        | OCRA Value |
            +-----------------+------------------+------------+
            | Standard 64Byte | SRV11110CLI22220 |  18806276  |
            | Standard 64Byte | SRV11111CLI22221 |  70020315  |
            | Standard 64Byte | SRV11112CLI22222 |  01600026  |
            | Standard 64Byte | SRV11113CLI22223 |  18951020  |
            | Standard 64Byte | SRV11114CLI22224 |  32528969  |
            +-----------------+------------------+------------+

And the client label, with the PSHA1 suite πŸ’–

                 Client -- OCRA-1:HOTP-SHA512-8:QA08-PSHA1

C.3. Plain Signature βœοΈπŸ¦‹

In this mode, Q is the signature challenge, so it's giving signing vibes πŸ’«

Here's the Standard 32Byte key set with SIG challenges:

                +-----------------+----------+------------+
                |       Key       |     Q    | OCRA Value |
                +-----------------+----------+------------+
                | Standard 32Byte | SIG10000 |  53095496  |
                | Standard 32Byte | SIG11000 |  04110475  |
                | Standard 32Byte | SIG12000 |  31331128  |
                | Standard 32Byte | SIG13000 |  76028668  |
                | Standard 32Byte | SIG14000 |  46554205  |
                +-----------------+----------+------------+

And its suite:

                         OCRA-1:HOTP-SHA256-8:QA08

Last but definitely not least, the Standard 64Byte key with longer SIG challenges and a T column πŸŽ€

          +-----------------+------------+---------+------------+
          |       Key       |      Q     |    T    | OCRA Value |
          +-----------------+------------+---------+------------+
          | Standard 64Byte | SIG1000000 | 132d0b6 |  77537423  |
          | Standard 64Byte | SIG1100000 | 132d0b6 |  31970405  |
          | Standard 64Byte | SIG1200000 | 132d0b6 |  10235557  |
          | Standard 64Byte | SIG1300000 | 132d0b6 |  95213541  |
          | Standard 64Byte | SIG1400000 | 132d0b6 |  65360607  |
          +-----------------+------------+---------+------------+

And the final suite label:

                       OCRA-1:HOTP-SHA512-8:QA10-T1M

Authors' Addresses πŸŒˆπŸ’Œ

Meet the crew who built this! Here's where you can find each of them 🫢

David M'Raihi:

David M'Raihi
Verisign, Inc.
487 E. Middlefield Road
Mountain View, CA  94043
USA

EMail: davidietf@gmail.com

Johan Rydell:

Johan Rydell
Portwise, Inc.
275 Hawthorne Ave, Suite 119
Palo Alto, CA  94301
USA

EMail: johanietf@gmail.com

Siddharth Bajaj:

Siddharth Bajaj
Symantec Corp.
350 Ellis Street
Mountain View, CA  94043
USA

EMail: siddharthietf@gmail.com

Salah Machani:

Salah Machani
Diversinet Corp.
2225 Sheppard Avenue East, Suite 1801
Toronto, Ontario  M2J 5C2
Canada

EMail: smachani@diversinet.com

David Naccache:

David Naccache
Ecole Normale Superieure
ENS DI, 45 rue d'Ulm
Paris,   75005
France

EMail: david.naccache@ens.fr

That's a wrap, bestie! πŸŽ‰πŸ’–βœ¨

πŸ“¦ where this page comes from