package otp

  1. Overview
  2. Docs
Time-base One Time Password (OTP) based on RFC6238 with an HMAC-SHA1 algorithm and a 6 digits code in OCAML

Install

dune-project
 Dependency

Authors

Maintainers

Sources

0.2.2.tar.gz
md5=358389b8f0869e47ecee646d39ce315b
sha512=46982fc43ecc8ed857ef19add6a3dee6b33309d2fc957faf44d3e9547f173ddbfe137f9307437435d0534f7a999fa9dc4157ab74c4b96a3702805b3f3039ced4

doc/otp/Otp/index.html

Module OtpSource

This library implements the Time-based One Time Password RFC 6238 with an HMAC-SHA1 algorithm and a 6 digits code. It relies on the Cryptokit library for cryptography operations, as well as the Base32 library for base32 encoding. The library generates a QR Code with the qrc library. It is tested against all test vectors provided in RFC 6238 and the test suite provides as well a dynamic test which requires the use of an client authenticator (like Google Authenticator or Microsoft Authenticator) as a final test.

# Get Started

There are two phases to setup an OTP : 1. the registration : that's where a secret is shared by the server to the client. 2. the authentication : that's when the client enters the 6 digits code to authenticate.

## Registration On the server side :

``` let rng = Cryptokit.Random.secure_rng in create a random generator let s = generate_secret rng in generate a secret let u = generate_totp_uri "MyWebSite" s "Michel" in embeds this secret into a specificaly crafted URI that authenticators can understand let qr = Otp.uri2qrcode u in transform this URI into a QRCode that can be display in an html page let file = open_out "test.html" in let fmt = Format.formatter_of_out_channel file in let () = Format.fprintf fmt "<html> <head></head> <body> <h1> TOTP QRCode </h1> %s </body> </html>" qr in let () = Format.pp_print_flush fmt () in let () = close_out file in let () = print_endline "\nOpen the file test.html and scann the QRCode with a client OTP (like Microsoft Authenticator)" ```

## Authentication Then for the authentication :

``` print_endline "Enter the six digit code to authenticate Michel on MyWebSite" let code = read_line () in if ((String.length code) != 6) then print_endline "Error, the code must have 6 and only 6 digits" else let digits = Int32.to_int (Int32.of_string code) in let c = totp_counter () in let r = verify s c digits in match r with | Result.Error e -> print_endline e | Result.Ok resync -> Printf.printf "The code is good, Michel is authenticated on MyWebSite. Drift : %d steps" resync ```

Sourcetype counter =
  1. | Counter of bytes
Sourceval generate_secret : ?nb_bits:int -> Cryptokit.Random.rng -> string

Generates a random string of nb_bits bits. If nb_bits is not a multiple of 8, the length of the string is rounded to the nearest integer toward 0. nb_bits : number of bits of the generated secrets. Default to 160 bits. Must be a multiple of 8 rng : a random generator, as for instance, provided by Cryptokit.Randome.secure_rng

Sourceval generate_totp_uri : ?algo:string -> ?nb_digits:int -> ?period:Stdint.uint64 -> string -> string -> string -> string

generate_totp_uri algo nb_digits period label secret issuer Generates an uri following the Key Uri Format

  • parameter algo

    Only support SHA1 (as most of authenticator clients) which is the default

  • parameter nb_digits

    Number of digits of the generated one-time-password. The default is 6 digits

  • parameter period

    The time step equivalent of the counter increment in second. Default value is 30 seconds, as in most authenticator clients. Refered to as "X" in the RFC 6238.

  • parameter label

    A name for the client's account which registers an OTP for.

  • parameter secret

    The secret to be shared with the authenticator client.

  • parameter issuer

    The name of the issuer of the OTP. (e.g. the name of the website)

Sourceval totp_counter : ?period:Stdint.uint64 -> ?t0:Stdint.uint64 -> ?drift:Stdint.uint64 -> unit -> counter

Generates a counter to be used in the time-based one time password procedure with a secret to verify a given code. The counter can also be incremented using the function Core.increment.

  • parameter period

    The time step equivalent of the counter increment in seconds. Default value is 30 seconds, as in most authenticator clients. Refered to as "X" in the RFC 6238.

  • parameter t0

    The Unix time to start counting time steps (default value is 0, i.e., the Unix epoch) and is also a system parameter.

  • parameter drift

    This parameter account for a possible clock drifts between a client and a validation server. This drift is the maximum number of backward time step to from which the verification process must start with. The total number of steps (or increments) that will be used to check a given code/digits is the threshold argument of the verify function.

  • returns

    A counter to be use with a secret to verify a code/digits.

Sourceval verify : ?threshold:int -> string -> counter -> int -> (int, string) result

verify threshold secret counter digits verifies that the digits are correct given the secret and the counter, by computing the digits and comparing them with the one provided.

  • parameter threshold

    Synchronization threshold corresponding to the maximum number of successive increments and verifications tried until concluding the digits are not correct. Default value is seuil_synchro.

  • parameter secret

    The secret initially shared with the authenticator client and used to compute the digits on the server side.

  • parameter counter

    The counter used to compute the digits. It should be provided by the totp_counter function.

  • parameter digits

    The digits to be verified, provided by the authenticator client.

  • returns

    Result.t.Ok with an integer mentioning the number of successive increments of the counter that have been needed to validate the digits (drift). This number must be less then seuil_synchro. Should not be more than 2 for well synchronised clocks and no latency on the network. Result.t.Error otherwise with a message indicating "Invalid code".

Sourceval uri2qrcode : string -> string

Transforms an uri provided by generate_totp_uri into a 50x50 mm2 qrcode embedded into an html svg element (container) that can be imported into any html page.

<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='50mm' height='50mm' viewBox='0 0 53 53'>
  <rect width='53' height='53' fill='white'/> <path fill='black' d='
   M 4,4 l 1,0 0,1 -1,0 z
   M 5,4 l 1,0 0,1 -1,0 z
   M 6,4 l 1,0 0,1 -1,0 z
   ...
   M 43,48 l 1,0 0,1 -1,0 z
   M 45,48 l 1,0 0,1 -1,0 z
  ' />
</svg>
Sourcemodule Core : sig ... end

This module is the core of the library and its functions are not exposed except for testing purpose. Do note rely on it for production.