Giter Club home page Giter Club logo

boringauth's Introduction

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))

boringauth's People

Contributors

breard-r avatar hellow554 avatar kpcyrd avatar yetanotherminion avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

boringauth's Issues

TOTP / HOTP does not match other implementations?

In testing this crate's TOTP implementation against Yubico Authenticator, I found that the (default, so 6-digit SHA-1) TOTP codes generated by Yubico Authenticator were not accepted by TOTP::is_valid(). I tested another implementation that I wrote many years ago in Python, whose codes did match Yubico Authenticator. I then came up with a Rust implementation that matches Yubico Authenticator and my older Python code:

fn totp_valid(secret: &[u8], code: &str, tolerance: u64) -> bool {
    assert!(tolerance < 7);
    let testing = u32::from_str(code).unwrap();
    let anchor = SystemTime::now()
        .duration_since(time::UNIX_EPOCH)
        .unwrap()
        .as_secs()
        / 30;
    let key = hmac::Key::new(hmac::HMAC_SHA1_FOR_LEGACY_USE_ONLY, secret);
    let mut tested = [false; 16];

    for i in (7u64 - tolerance)..(8 + tolerance) {
        let current = (anchor + i) - 8;
        let tag = hmac::sign(&key, &current.to_be_bytes()[..]);
        let offset = (tag.as_ref()[19] & 15) as usize;
        let p = u32::from_be_bytes(tag.as_ref()[offset..offset + 4].try_into().unwrap());
        tested[i as usize] = dbg!((p & 0x7fff_ffff) % 1_000_000) == testing;
    }

    tested.iter().fold(false, |acc, p| acc | p)
}

Document mistake on default hash algorithm of TOTP

All the document says the default hash algorithm of TOTP is SHA1, but apparently the code says it is SHA256.

Screenshot of the document
image
image

Screenshot of the code
image

Althrough sha256 may be more secured than sha1. Still most authenticator apps(Microsoft or Google) do not support it. I guess it's more suitable to set the default SHA1.

Can you bump ring?

Since commits are slow right now, how about a ring 0.15 and then afterwards a ring 0.16 release so that people using web frameworks which also depend on ring have a chance to use BoringAuth?

Would be cool. :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.