#hotp #totp #otp #2fa

boringauth

Straightforward password, passphrase, TOTP, and HOTP user authentication

8 unstable releases (3 breaking)

Uses old Rust 2015

0.9.0 Oct 11, 2019
0.8.0 May 28, 2019
0.7.0 Aug 10, 2018
0.6.4 May 20, 2018
0.6.1 Jun 4, 2017

#315 in Authentication

Download history 427/week @ 2023-11-27 325/week @ 2023-12-04 318/week @ 2023-12-11 285/week @ 2023-12-18 173/week @ 2023-12-25 264/week @ 2024-01-01 356/week @ 2024-01-08 273/week @ 2024-01-15 286/week @ 2024-01-22 379/week @ 2024-01-29 259/week @ 2024-02-05 243/week @ 2024-02-12 270/week @ 2024-02-19 384/week @ 2024-02-26 456/week @ 2024-03-04 142/week @ 2024-03-11

1,257 downloads per month
Used in kraken_api

GPL-2.0 license

120KB
2.5K SLoC

BoringAuth

Build Status BoringAuth on crates.io

BoringAuth is a collection of tools for user authentication. BoringAuth is a fork of LibreAuth that chooses to use the actively developed ring crypto crate over the dead rust-crypto crate for its crypto primitives.

Ring compatibility chart.

BoringAuth Ring
v0.6.4 0.12
v0.7.0 0.13

Features

  • Password / passphrase authentication
    • no character-set limitation
    • reasonable lenth limit (security vs. DOS)
    • strong, evolutive and retro-compatible password derivation functions
    • crypt() compatibility
  • HOTP - HMAC-based One-time Password Algorithm (OATH - RFC 4226)
    • the key can be passed as bytes, an ASCII string, an hexadicimal string or a base32 string
    • customizable counter
    • customizable hash function (sha1, sha256, sha512)
    • customizable output length
    • customizable output alphabet
  • TOTP - Time-based One-time Password Algorithm (OATH - RFC 6238)
    • the key can be passed as bytes, an ASCII string, an hexadicimal string or a base32 string
    • customizable timestamp
    • customizable period
    • customizable initial time (T0)
    • customizable hash function (sha1, sha256, sha512)
    • customizable output length
    • customizable output alphabet
    • customizable positive and negative period tolerance
  • YubiKey OTP (Yubico)
    • virtual device API
    • client API
    • server API
  • U2F - Universal 2nd Factor (FIDO Alliance)
    • virtual device API
    • client API
    • server API

Using within a Rust project

You can find BoringAuth on crates.io and include it in your Cargo.toml:

boringauth = "*"

Using outside Rust

In order to build BoringAuth, you will need both the rust compiler and cargo.

$ git clone https://github.com/ThinkAlexandria/boringauth.git
$ cd boringauth
$ make
$ make install prefix=/usr

Quick examples

Rust

extern crate boringauth;
use boringauth::oath::TOTPBuilder;

let key = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ".to_string();
let code = TOTPBuilder::new()
    .base32_key(&key)
    .finalize()
    .unwrap()
    .generate();
assert_eq!(code.len(), 6);

C

#include <stdio.h>
#include <boringauth.h>

int main(void) {
  struct boringauth_totp_cfg cfg;
  char   code[7], key[] = "12345678901234567890";

  if (boringauth_totp_init(&cfg) != LIBREAUTH_OTP_SUCCESS) {
    return 1;
  }
  cfg.key = key;
  cfg.key_len = sizeof(key);
  if (boringauth_totp_generate(&cfg, code) != LIBREAUTH_OTP_SUCCESS) {
    return 2;
  }

  printf("%s\n", code);

  return 0;
}
$ cc -o totp totp.c -lboringauth
$ ./totp
848085

Python

from ctypes.util import find_library
from struct import Struct
from ctypes import *

class TOTPcfg(Structure):
    _fields_ = [
        ('key', c_char_p),
        ('key_len', c_size_t),
        ('timestamp', c_longlong),
        ('period', c_uint),
        ('initial_time', c_ulonglong),
        ('output_len', c_size_t),
        ('output_base', c_char_p),
        ('output_base_len', c_size_t),
        ('hash_function', c_int),
    ]

def get_totp():
    key = b'12345678901234567890'
    lib_path = find_library('boringauth') or 'target/release/libboringauth.so'
    lib = cdll.LoadLibrary(lib_path)
    cfg = TOTPcfg()
    if lib.boringauth_totp_init(byref(cfg)) != 0:
        return
    cfg.key_len = len(key)
    cfg.key = c_char_p(key)
    code = create_string_buffer(b'\000' * cfg.output_len)
    if lib.boringauth_totp_generate(byref(cfg), code) != 0:
        return
    return str(code.value, encoding="utf-8")

if __name__ == '__main__':
    code = get_totp()
    print('{}'.format(code))

Dependencies

~8.5MB
~244K SLoC