23 个稳定版本 (4 个主要版本)
5.6.0 | 2024年7月24日 |
---|---|
5.5.1 | 2024年1月19日 |
5.4.0 | 2023年10月4日 |
5.1.0 | 2023年7月15日 |
0.5.0 |
|
#22 in 身份验证
55,903 个月下载量
在 38 个 Crates (27 个直接使用) 中使用
87KB
1.5K SLoC
totp-rs
此库允许根据 TOTP 创建 2FA 身份验证令牌,验证这些令牌,并具有可配置的时间偏移量、每个令牌的有效时间、算法和数字位数!默认功能尽可能保持轻量级,以确保小型二进制文件和较短的编译时间。
它现在支持解析 otpauth URLs 到 totp 对象,并具有合理的默认值。
请注意,某些身份验证器应用程序将接受 SHA256
和 SHA512
算法,但会静默回退到 SHA1
,这将导致由于算法不匹配而导致 check()
函数失败。
功能
qr
使用可选功能 "qr",您可以使用它生成 base64 png 二维码。这将启用 otpauth
功能。
otpauth
使用可选功能 "otpauth",支持从 otpauth
URL 解析 TOTP 参数,并生成 otpauth
URL。它向 TOTP
添加了 2 个字段。
serde_support
使用可选功能 "serde_support",库定义的类型 TOTP
和 Algorithm
将支持反序列化和序列化。
gen_secret
使用可选功能 "gen_secret",将为您生成一个秘密以存储在数据库中。
zeroize
当 TOTP 结构被丢弃时,安全地将秘密信息归零。
steam
添加对 Steam TOTP 令牌的支持。
示例
摘要
- 理解秘密
- 生成令牌
- 启用二维码生成
- 启用 serde 支持
- 启用 otpauth url 支持
- 启用 gen_secret 支持
- 使用符合 RFC-6238 的默认值
- 从 steam 秘密生成新的 TOTP
理解秘密
此新类型被添加为区分原始和已 base32 编码的秘密。
Secret::Raw("TestSecretSuperSecret".as_bytes().to_vec())
等同于
Secret::Encoded("KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ".to_string())
生成令牌
将其添加到您的 Cargo.toml
[dependencies]
totp-rs = "^5.0"
然后您可以这样做
use std::time::SystemTime;
use totp_rs::{Algorithm, TOTP, Secret};
fn main() {
let totp = TOTP::new(
Algorithm::SHA1,
6,
1,
30,
Secret::Raw("TestSecretSuperSecret".as_bytes().to_vec()).to_bytes().unwrap(),
).unwrap();
let token = totp.generate_current().unwrap();
println!("{}", token);
}
这相当于
use std::time::SystemTime;
use totp_rs::{Algorithm, TOTP, Secret};
fn main() {
let totp = TOTP::new(
Algorithm::SHA1,
6,
1,
30,
Secret::Encoded("KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ".to_string()).to_bytes().unwrap(),
).unwrap();
let token = totp.generate_current().unwrap();
println!("{}", token);
}
带有二维码生成
将其添加到您的 Cargo.toml
[dependencies.totp-rs]
version = "^5.3"
features = ["qr"]
然后您可以这样做
use totp_rs::{Algorithm, TOTP, Secret};
fn main() {
let totp = TOTP::new(
Algorithm::SHA1,
6,
1,
30,
Secret::Encoded("KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ".to_string()).to_bytes().unwrap(),
Some("Github".to_string()),
"[email protected]".to_string(),
).unwrap();
let qr_code = totp.get_qr_base64()?;
println!("{}", qr_code);
}
支持 serde
将其添加到您的 Cargo.toml
[dependencies.totp-rs]
version = "^5.0"
features = ["serde_support"]
支持 otpauth url
将其添加到您的 Cargo.toml
[dependencies.totp-rs]
version = "^5.0"
features = ["otpauth"]
然后您可以这样做
use totp_rs::TOTP;
fn main() {
let otpauth = "otpauth://totp/GitHub:[email protected]?secret=KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ&issuer=GitHub";
let totp = TOTP::from_url(otpauth).unwrap();
println!("{}", totp.generate_current().unwrap());
}
支持 gen_secret
将其添加到您的 Cargo.toml
[dependencies.totp-rs]
version = "^5.3"
features = ["gen_secret"]
然后您可以这样做
use totp_rs::{Algorithm, TOTP, Secret};
fn main() {
let totp = TOTP::new(
Algorithm::SHA1,
6,
1,
30,
Secret::default().to_bytes().unwrap(),
Some("Github".to_string()),
"[email protected]".to_string(),
).unwrap();
let qr_code = totp.get_qr_base64()?;
println!("{}", qr_code);
}
这相当于
use totp_rs::{Algorithm, TOTP, Secret};
fn main() {
let totp = TOTP::new(
Algorithm::SHA1,
6,
1,
30,
Secret::generate_secret().to_bytes().unwrap(),
Some("Github".to_string()),
"[email protected]".to_string(),
).unwrap();
let qr_code = totp.get_qr_base64()?;
println!("{}", qr_code);
}
使用符合 RFC-6238 的默认值
您可以进行如下操作
use totp_rs::{Algorithm, TOTP, Secret, Rfc6238};
fn main () {
let mut rfc = Rfc6238::with_defaults(
Secret::Encoded("KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ".to_string()).to_bytes().unwrap(),
)
.unwrap();
// optional, set digits
rfc.digits(8).unwrap();
// create a TOTP from rfc
let totp = TOTP::from_rfc6238(rfc).unwrap();
let code = totp.generate_current().unwrap();
println!("code: {}", code);
}
使用 gen_secret
功能,您可以更进一步,并使所有值默认且安全。
注意:使用 otpauth
功能,TOTP.issuer
将为 None
,而 TOTP.account_name
将为 """"
。在生成 URL/QRCode 之前,请务必设置这些字段。
fn main() {
let totp = TOTP::default();
let code = totp.generate_current().unwrap();
println!("code: {}", code);
}
从 steam 秘密生成新的 TOTP
将其添加到您的 Cargo.toml
[dependencies.totp-rs]
version = "^5.3"
features = ["steam"]
然后您可以这样做
use totp_rs::{TOTP, Secret};
fn main() {
let totp = TOTP::new_steam(
Secret::Encoded("KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ".to_string()).to_bytes().unwrap(),
).unwrap();
let code = totp.generate_current().unwrap();
println!("code: {}", code);
}
依赖项
~0.5–1.7MB
~37K SLoC