package otp
Install
dune-project
Dependency
Authors
Maintainers
Sources
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 ```
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
val generate_totp_uri :
?algo:string ->
?nb_digits:int ->
?period:Stdint.uint64 ->
string ->
string ->
string ->
stringgenerate_totp_uri algo nb_digits period label secret issuer Generates an uri following the Key Uri Format
val totp_counter :
?period:Stdint.uint64 ->
?t0:Stdint.uint64 ->
?drift:Stdint.uint64 ->
unit ->
counterGenerates 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.
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.
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>