#hotp #totp #otp #2fa

boringauth

简单直接的密码、短语、TOTP 和 HOTP 用户认证

8 个不稳定版本 (3 个破坏性更新)

使用旧的 Rust 2015

0.9.0 2019 年 10 月 11 日
0.8.0 2019 年 5 月 28 日
0.7.0 2018 年 8 月 10 日
0.6.4 2018 年 5 月 20 日
0.6.1 2017 年 6 月 4 日

#376 in 认证

Download history 448/week @ 2024-03-13 327/week @ 2024-03-20 355/week @ 2024-03-27 364/week @ 2024-04-03 310/week @ 2024-04-10 383/week @ 2024-04-17 319/week @ 2024-04-24 229/week @ 2024-05-01 321/week @ 2024-05-08 217/week @ 2024-05-15 265/week @ 2024-05-22 259/week @ 2024-05-29 392/week @ 2024-06-05 308/week @ 2024-06-12 354/week @ 2024-06-19 345/week @ 2024-06-26

1,457 每月下载次数
kraken_api 中使用

GPL-2.0 许可证

120KB
2.5K SLoC

BoringAuth

Build Status BoringAuth on crates.io

BoringAuth 是一组用于用户认证的工具。BoringAuth 是从 LibreAuth 分支出来的,选择使用活跃开发的 ring 加密库,而不是已废弃的 rust-crypto 加密库。

Ring 兼容性图表。

BoringAuth Ring
v0.6.4 0.12
v0.7.0 0.13

功能

  • 密码/短语认证
    • 无字符集限制
    • 合理的长度限制(安全性 vs. DOS
    • 强大、可演化和向后兼容的密码派生函数
    • crypt() 兼容性
  • HOTP - 基于HMAC的一次性密码算法(《OATH - RFC 4226
    • 密钥可以是字节、ASCII字符串、十六进制字符串或base32字符串
    • 可定制计数器
    • 可定制哈希函数(sha1, sha256, sha512)
    • 可定制输出长度
    • 可定制输出字母表
  • TOTP - 基于时间的一次性密码算法(《OATH - RFC 6238
    • 密钥可以是字节、ASCII字符串、十六进制字符串或base32字符串
    • 可定制时间戳
    • 可定制周期
    • 可定制初始时间(T0)
    • 可定制哈希函数(sha1, sha256, sha512)
    • 可定制输出长度
    • 可定制输出字母表
    • 可定制正负周期容差
  • YubiKey OTP(《Yubico)
    • 虚拟设备API
    • 客户端API
    • 服务器API
  • U2F - 通用第二因素(《FIDO Alliance)
    • 虚拟设备API
    • 客户端API
    • 服务器API

Rust 项目中使用

您可以在 crates.io 上找到 BoringAuth 并将其包含在您的 Cargo.toml

boringauth = "*"

在 Rust 之外使用

为了构建 BoringAuth,您将需要 rust 编译器cargo

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

快速示例

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

依赖项

~8.5MB
~244K SLoC