Rust TOTP双因素认证库totp-lite的使用:轻量级时间同步一次性密码生成器

Rust TOTP双因素认证库totp-lite的使用:轻量级时间同步一次性密码生成器

简介

totp-lite是一个简单、正确的TOTP(基于时间的一次性密码)库。TOTP是一种有效的客户端认证方式,因为有效密码在攻击者猜测之前就会过期。该库提供了符合RFC6238规范的TOTP实现,并提供了简单的接口。

使用方法

totp函数可能是你最需要的。它使用默认的30秒时间步长并生成8位输出:

use std::time::{SystemTime, UNIX_EPOCH};
use totp_lite::{totp, Sha512};

// 与认证服务协商的密钥
let password: &[u8] = b"secret";

// 从Unix纪元开始的秒数
let seconds: u64 = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();

// 通过类型参数指定所需的哈希算法
// 也可使用`Sha1`和`Sha256`
let result: String = totp::<Sha512>(password, seconds);
assert_eq!(8, result.len());

如果需要完全控制算法配置,可以考虑使用totp_custom函数。

完整示例代码

下面是一个完整的TOTP生成和验证示例:

use std::time::{SystemTime, UNIX_EPOCH};
use totp_lite::{totp, totp_custom, Sha1, Sha256, Sha512};

fn main() {
    // 1. 基本用法示例
    let secret = b"my_super_secret_key";
    
    // 获取当前时间戳(秒)
    let timestamp = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_secs();
    
    // 使用默认设置生成TOTP (SHA1, 30秒间隔, 8位数字)
    let code = totp::<Sha1>(secret, timestamp);
    println!("Generated TOTP code: {}", code);
    
    // 2. 自定义设置示例
    let custom_code = totp_custom::<Sha256>(
        secret,       // 密钥
        timestamp,    // 时间戳
        60,           // 时间步长(秒)
        6,            // 数字位数
    );
    println!("Custom TOTP code: {}", custom_code);
    
    // 3. 使用SHA512算法
    let sha512_code = totp::<Sha512>(secret, timestamp);
    println!("SHA512 TOTP code: {}", sha512_code);
    
    // 4. 验证TOTP代码(简单示例)
    let user_provided_code = "12345678"; // 假设这是用户输入的代码
    if user_provided_code == code {
        println!("Authentication successful!");
    } else {
        println!("Authentication failed!");
    }
}

完整示例demo

下面是一个更完整的TOTP实现示例,包含生成和验证功能:

use std::time::{SystemTime, UNIX_EPOCH};
use totp_lite::{totp, totp_custom, Sha1};

// TOTP验证器结构体
struct TotpAuthenticator {
    secret: Vec<u8>,
    time_step: u64,
    digits: u32,
}

impl TotpAuthenticator {
    // 创建新的验证器实例
    fn new(secret: &[u8], time_step: u64, digits: u32) -> Self {
        TotpAuthenticator {
            secret: secret.to_vec(),
            time_step,
            digits,
        }
    }

    // 生成当前TOTP代码
    fn generate(&self) -> String {
        let timestamp = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_secs();
        
        totp_custom::<Sha1>(
            &self.secret,
            timestamp,
            self.time_step,
            self.digits,
        )
    }

    // 验证用户提供的代码
    fn verify(&self, code: &str) -> bool {
        let current_code = self.generate();
        current_code == code
    }
}

fn main() {
    // 初始化TOTP验证器
    let authenticator = TotpAuthenticator::new(b"my_shared_secret", 30, 6);
    
    // 生成TOTP代码
    let code = authenticator.generate();
    println!("Current TOTP code: {}", code);
    
    // 模拟用户输入
    let user_input = "123456"; // 替换为实际用户输入
    
    // 验证代码
    if authenticator.verify(user_input) {
        println!("验证成功!");
    } else {
        println!("验证失败!");
    }
}

资源

  • RFC6238: TOTP规范
  • RFC6238勘误表

许可证

MIT License


1 回复

Rust TOTP双因素认证库totp-lite使用指南

简介

totp-lite是一个轻量级的Rust库,用于生成和验证基于时间的一次性密码(TOTP),这是双因素认证(2FA)的常用实现方式。它完全兼容RFC 6238标准,支持Google Authenticator等常见认证器。

主要特性

  • 轻量级实现,无额外依赖
  • 支持标准TOTP算法
  • 可自定义时间步长和密码长度
  • 简单的API设计

完整示例代码

下面是一个完整的TOTP实现示例,包含生成、验证和QR码URI生成功能:

use std::time::{SystemTime, UNIX_EPOCH};
use totp_lite::{totp_custom, Sha1, Sha256, Sha512};

fn main() {
    // 1. 生成TOTP代码
    let secret = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ"; // Base32编码的共享密钥
    let timestamp = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_secs();

    // 使用不同哈希算法生成TOTP
    let code_sha1 = totp_custom::<Sha1>(30, 6, secret.as_bytes(), timestamp);
    let code_sha256 = totp_custom::<Sha256>(30, 6, secret.as_bytes(), timestamp);
    let code_sha512 = totp_custom::<Sha512>(30, 6, secret.as_bytes(), timestamp);

    println!("当前TOTP代码(SHA1): {}", code_sha1);
    println!("当前TOTP代码(SHA256): {}", code_sha256);
    println!("当前TOTP代码(SHA512): {}", code_sha512);

    // 2. 验证TOTP代码
    let user_input = 123456; // 模拟用户输入
    let is_valid = verify_totp(secret, user_input, timestamp);
    println!("验证结果: {}", if is_valid { "成功" } else { "失败" });

    // 3. 带时间漂移的验证
    let is_valid_with_drift = verify_totp_with_drift(secret, user_input, timestamp, 1);
    println!("带漂移验证结果: {}", if is_valid_with_drift { "成功" } else { "失败" });

    // 4. 生成QR码URI
    let otp_uri = generate_otp_uri(secret, "MyRustApp", "user@example.com");
    println!("OTP URI: {}", otp_uri);
}

// 验证TOTP代码
fn verify_totp(secret: &str, code: u32, timestamp: u64) -> bool {
    let generated_code = totp_custom::<Sha1>(30, 6, secret.as_bytes(), timestamp);
    generated_code == code
}

// 带时间漂移的验证
fn verify_totp_with_drift(secret: &str, code: u32, timestamp: u64, drift: i64) -> bool {
    for i in -drift..=drift {
        let t = (timestamp as i64 + i * 30) as u64;
        let generated_code = totp_custom::<Sha1>(30, 6, secret.as_bytes(), t);
        if generated_code == code {
            return true;
        }
    }
    false
}

// 生成OTP URI
fn generate_otp_uri(secret: &str, issuer: &str, account: &str) -> String {
    format!(
        "otpauth://totp/{}:{}?secret={}&issuer={}&algorithm=SHA1&digits=6&period=30",
        issuer, account, secret, issuer
    )
}

实际应用建议

  1. 密钥管理
// 使用环境变量获取密钥
use std::env;

fn get_secret() -> String {
    env::var("TOTP_SECRET").expect("TOTP_SECRET环境变量未设置")
}
  1. 安全存储
// 使用secrecy库保护内存中的密钥
use secrecy::{Secret, ExposeSecret};

let secret = Secret::new("GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ".to_string());
let code = totp_custom::<Sha1>(30, 6, secret.expose_secret().as_bytes(), timestamp);
  1. 时间同步
// 使用NTP同步时间
use std::time::SystemTime;

fn get_synced_timestamp() -> u64 {
    SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_secs()
}

注意事项

  1. 生产环境中不要硬编码密钥
  2. 考虑使用HSM或KMS服务管理密钥
  3. 实现适当的重试限制防止暴力破解
  4. 记录失败的验证尝试用于安全审计

这个完整示例展示了totp-lite库的主要功能,您可以根据实际需求进行调整和扩展。

回到顶部