Skip to content

ZenProjects/OCRAjs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OCRA (RFC 6287) JavaScript Implementation

An implementation of the OATH Challenge-Response Algorithm (OCRA) as specified in RFC 6287.

RFC 6287 Compliance

This implementation fully complies with RFC 6287 and passes all official test vectors:

  • All hash algorithms (SHA1, SHA256, SHA512)
  • All data input formats (C, Q, P, S, T)
  • All question formats (N, A, H)

Features

  • Developped to works only in browsers
    • Chrome 49+
    • Firefox 45+
    • Safari 10.1+
    • Opera 36+
    • Edge 13+
  • Work with : CryptoJS; jsSHA and Browser Web Crypto API

RFC Conformance Test

Running RFC conformance Test Vectors her

Quick Start

Browser Usage

<!-- Include a crypto library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js"></script>

<!-- Include OCRA -->
<script src="ocra.js"></script>

<script>
async function generateCode() {
  const code = await OCRA.generate(
    "OCRA-1:HOTP-SHA1-6:QN08",  // Suite
    "12345678901234567890",      // Secret key
    "12345678"                   // Challenge
  );
  console.log("OCRA Code:", code);
}
</script>

API Reference

OCRA.generate(suite, key, challenge, [counter], [password], [sessionInfo], [timestamp])

Generates an OCRA code according to the specified suite.

Parameters

Parameter Type Required Description
suite string OCRA suite specification (e.g., "OCRA-1:HOTP-SHA1-6:QN08")
key Hex Encoded string Secret key (HEX encoded)
challenge Hex Encoded string Challenge/question string (HEX encoded, type to encode depend on suite QNxx/QAxx/QHxx, QN = BigInt hexx String encoded, QA = String Hex Encoded, QH = Raw Hex String, max 128 bytes)
counter Big Int Hex Encoded String Counter value (for suites with 'C') (BigInt HEX encoded, max 16 bytes)
password Hex Encoded string Password (for suites with 'P') (HEX encoded, max 20 bytes)
sessionInfo Hex Encoded string Session information (for suites with 'S') (HEX encoded, max bytes depend on the Ocra Suite : 64, 128, 512)
timestamp Big Int Hex Encoded Timestamp (for suites with 'T') (BigInt Hex Encoded, the signification of the depend on the Time Step Granularity of the Ocra Suite)

Returns

  • Promise<string> - The generated OCRA code

Ocra Suite Format Structure

An OCRASuite value follows this general format:

<Algorithm>:<CryptoFunction>:<DataInput>

The OCRASuite is composed of three main components separated by colons (:):

  1. Algorithm - Specifies the OCRA version
  2. CryptoFunction - Defines the cryptographic function used
  3. DataInput - Describes the input parameters for computation

Component Specifications

1. Algorithm Component

Format: OCRA-v

  • Description: Indicates the version of OCRA being used
  • Values: OCRA-1 (RFC 6287 specifies version 1)
  • Example: OCRA-1

2. CryptoFunction Component

Format: HOTP-H-t

  • Description: Specifies the HMAC-based function and truncation parameters
  • Components:
    • HOTP - Fixed prefix indicating HOTP-based computation
    • H - Hash function (SHA1, SHA256, SHA512)
    • t - Truncation length in decimal digits (0, 4-10)

Supported Values:

Function Name HMAC Function Truncation Size
HOTP-SHA1-t HMAC-SHA1 0, 4-10
HOTP-SHA256-t HMAC-SHA256 0, 4-10
HOTP-SHA512-t HMAC-SHA512 0, 4-10

Common Examples:

  • HOTP-SHA1-6 (default) - SHA1 with 6-digit truncation
  • HOTP-SHA256-8 - SHA256 with 8-digit truncation
  • HOTP-SHA512-4 - SHA512 with 4-digit truncation
  • HOTP-SHA1-0 - SHA1 with no truncation (full HMAC)

3. DataInput Component

Format: [C][|QFxx][|PH][|Snnn][|TG]

The DataInput component specifies which input parameters are used in the computation. Components are separated by hyphens (-) and include:

Counter (C) - Optional

  • Symbol: C
  • Description: 8-byte counter value synchronized between parties
  • Usage: Incremented on each computation request
  • Example: C

Challenge Question (Q) - Mandatory for most modes

  • Format: QFxx
  • Description: Challenge question with specified format and maximum length
  • Components:
    • Q - Fixed prefix for challenge
    • F - Format specifier
    • xx - Maximum length (04-64)

Format Specifiers:

Format (F) Type Length Range
A Alphanumeric 04-64
N Numeric 04-64
H Hexadecimal 04-64

Default: QN08 (Numeric, up to 8 digits)

Examples:

  • QN08 - Numeric challenge, max 8 digits
  • QA10 - Alphanumeric challenge, max 10 characters
  • QH16 - Hexadecimal challenge, max 16 nibbles

PIN/Password (P) - Optional

  • Format: PH
  • Description: Hashed version of PIN/password
  • Components:
    • P - Fixed prefix for password
    • H - Hash function (SHA1, SHA256, SHA512)

Supported Hash Functions:

  • PSHA1 - SHA1 hash of PIN/password (default)
  • PSHA256 - SHA256 hash of PIN/password
  • PSHA512 - SHA512 hash of PIN/password

Session Information (S) - Optional

  • Format: Snnn
  • Description: UTF-8 encoded session data
  • Components:
    • S - Fixed prefix for session
    • nnn - Length in bytes

Common Lengths:

  • S064 - 64 bytes (default)
  • S128 - 128 bytes
  • S256 - 256 bytes
  • S512 - 512 bytes

Timestamp (T) - Optional

  • Format: TG
  • Description: Time-based parameter
  • Components:
    • T - Fixed prefix for timestamp
    • G - Time-step granularity

Time-Step Granularity:

Granularity (G) Description Examples
[1-59]S Seconds 20S
[1-59]M Minutes 5M
[0-48]H Hours 24H

Default: T1M (1-minute time steps)

Usage Patterns

Challenge-Response Computation

Format: [C]|QFxx|[PH|Snnn|TG]

Examples:

  • QN08 - Simple numeric challenge
  • C-QN08-PSHA1 - Counter + numeric challenge + PIN
  • QA10-T1M - Alphanumeric challenge + timestamp

Plain Signature Computation

Format: [C]|QFxx|[PH|TG]

Examples:

  • QA08 - Alphanumeric signature challenge
  • QH8-S512 - Hex challenge + session info

OCRA Suite Examples

Basic Challenge-Response

OCRA-1:HOTP-SHA1-6:QN08
  • Version 1 OCRA
  • SHA1 with 6-digit truncation
  • Numeric challenge up to 8 digits

Advanced Authentication

OCRA-1:HOTP-SHA512-8:C-QN08-PSHA1
  • Version 1 OCRA
  • SHA512 with 8-digit truncation
  • Counter + numeric challenge + SHA1-hashed PIN

Timestamped Challenge

OCRA-1:HOTP-SHA256-6:QA10-T1M
  • Version 1 OCRA
  • SHA256 with 6-digit truncation
  • Alphanumeric challenge + 1-minute timestamps

Session-Based Signature

OCRA-1:HOTP-SHA1-4:QH8-S512
  • Version 1 OCRA
  • SHA1 with 4-digit truncation
  • Hex challenge + 512-byte session data

Notes

  1. Key Agreement: Client and server must agree on OCRASuite values during provisioning or negotiation
  2. Mutual Authentication: Requires two OCRASuite values (one for server, one for client computation)
  3. Default Values: When optional parameters are omitted, defaults apply (QN08, PSHA1, S064, T1M)
  4. Padding: Challenge/questions less than 128 bytes are padded with zeros to the right
  5. Encoding: Session information uses UTF-8 encoding
  6. Epoch Time: Timestamps based on Unix epoch (January 1, 1970, midnight UTC)

Examples

Basic OCRA Generation

const suite = "OCRA-1:HOTP-SHA1-6:QN08";
const key = "12345678901234567890";
const challenge = "12345678";

const code = await OCRA.generate(suite, key, challenge);
console.log(code); // e.g., "123456"

Using Hex Keys

const key = "3132333435363738393031323334353637383930";  // hex encoded seed key

const code = await OCRA.generate(
  "OCRA-1:HOTP-SHA1-6:QN08", 
  key,
  ORCA.bigIntToHex("00000000") // QN = numeric challenge
);

Counter-Based OCRA

const code = await OCRA.generate(
  "OCRA-1:HOTP-SHA1-6:C-QN08",
  key,
  ORCA.bigIntToHex("12345678"), // QN = numeric challenge
  ORCA.bigIntToHex("123")  // counter
);

Password-Protected OCRA

const code = await OCRA.generate(
  "OCRA-1:HOTP-SHA256-8:QN08-PSHA1",
  key, 
  ORCA.bigIntToHex("12345678"), // QN = numeric challenge
  undefined,                    // no counter
  OCRA.stringToHex("1234")      // PSHA1 = SHA1 password
);

Time-Based OCRA

const timestampMinutes = Math.floor(Date.now() / 60000); // Actual nulber of minute from epoch because set T1M in ocra suite

const code = await OCRA.generate(
  "OCRA-1:HOTP-SHA512-8:QN08-T1M",
  key,
  ORCA.bigIntToHex("12345678"),  // QN = numeric challenge
  undefined, // no counter
  undefined, // no password
  undefined, // no session
  ORCA.bigIntToHex(timestampMinutes)
);

Crypto Library Support

The implementation automatically detects and uses available crypto libraries in this order:

  1. WebCrypto API (default)
  2. CryptoJS (alternative)
  3. jsSHA (alternative)

Automatique detection :

const cryptoInfo = OCRA.getCryptoInfo();
console.log('Libraries available:', cryptoInfo.available);
console.log('Primary library:', cryptoInfo.primary);

CryptoJS Setup

<!-- Browser -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js"></script>

jsSHA Setup

<!-- Browser -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsSHA/3.3.1/sha.js"></script>

Error Handling

try {
  const code = await OCRA.generate(suite, key, challenge);
  console.log("Success:", code);
} catch (error) {
  console.error("OCRA Error:", error.message);
}

Common Errors

  • Invalid OCRA suite format - Malformed suite string
  • Invalid crypto function - Unsupported hash algorithm
  • Crypto library not supported - No compatible crypto library found
  • Algorithm X not supported with Y - Library doesn't support the algorithm

License

GNU Lesser General Public License v3.0 or later (LGPL-3.0-or-later)

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

About

OCRA: OATH Challenge-Response Algorithm implementation in Javascript

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors