2 个稳定版本
1.1.0 | 2024年6月18日 |
---|---|
1.0.0 | 2024年6月17日 |
#371 in 加密学
55KB
791 行
RFC 2289 单次密码
实现了 IETF RFC 2289 中描述的单次密码 (OTP) 算法,包括解析字符串和在词典单词与 OTP 值之间进行映射的函数。
此算法与今天广泛用于多因素身份验证的 TOTP 和 HOTP 算法不同:这些算法在其他的 RFC 中定义。然而,此算法在 IETF RFC 2444 中描述的 OTP
SASL 机制中使用。
安全性
请注意,此算法只定义了三种哈希算法,并且 所有这些算法都不再被认为是安全的。这些是
- MD4
- MD5
- SHA1
然而,我作为非专业人士认为,这些算法在 OTP 算法中使用的这种方式是完全可以接受的,因为 OTP 算法使用固定的种子和密码进行固定次数的哈希。尽管如此,我 强烈 建议只使用 sha1
算法。它是三者中最新的、最安全的。
如果将来有更多的算法被正式化,你应该在这里查看新算法:here.
我计划实现更多这样的算法,即使它们没有标准化。标准算法背后的原则在现代算法中具有明显的推论。如果您希望支持某个特定的算法,请提出请求!
功能标志
此库的功能标志包括
md4
:MD4 支持md5
:MD5 支持sha1
:SHA1 支持words
:词典单词的翻译dyndig
:支持实现digest::DynDigest
的任何摘要parsing
:解析 OTP 字符串
上述所有功能默认启用。
用法
假设你以以下字符串形式接收一个 OTP 挑战
otp-md5 499 ke1234 ext
按照如下方式解码此字符串
let challenge_str = "otp-md5 487 dog2";
let challenge = parse_otp_challenge(challenge_str).unwrap();
如果它是一个有效的字符串,你应该得到一个类似以下的数据结构
pub struct OTPChallenge <'a> {
pub hash_alg: &'a str,
pub hash_count: usize,
pub seed: &'a str,
}
您可以使用此数据结构按如下方式计算OTP
let extremely_secure_passphrase = "banana";
let otp = calculate_otp(
challenge.hash_alg,
extremely_secure_passphrase,
challenge.seed,
challenge.hash_count,
None,
).unwrap();
如果算法已理解,且没有其他问题,您应该得到一个 [u8; 8]
返回值(64位),这是您的OTP值。
您可以直接将此值转换为十六进制,并在其前面加上 hex:
以生成有效的OTP响应。
或者,您可以使用 convert_to_word_format
将其转换为规范字典定义的标准字典中的字典单词。用空格连接这些单词,并在前面加上 word:
。
如果实现OTP服务器,您可以像这样解析这些响应
let otp_response = "hex:5Bf0 75d9 959d 036f";
let r = parse_otp_response(&otp_response).unwrap();
如果语法有效,您应该得到一个如下所示的 OTPResponse
pub enum HexOrWords <'a> {
Hex(Hex64Bit),
Words(&'a str),
}
pub struct OTPInit <'a> {
pub current_otp: HexOrWords<'a>,
pub new_otp: HexOrWords<'a>,
pub new_alg: &'a str,
pub new_seq_num: usize,
pub new_seed: &'a str,
}
pub enum OTPResponse <'a> {
Init(OTPInit <'a>),
Current(HexOrWords<'a>)
}
服务器需要计算OTP并将该值与客户端提供的解码的十六进制或单词进行比较。您可以使用 decode_word_format_with_std_dict
将单词解码为二进制OTP值
let decoded = decode_word_format_with_std_dict(words).unwrap();
如果客户端响应是 Init
变体之一,服务器如何处理这是一个实现细节。
许可
版权所有 2024 (c) Jonathan M. Wilbur。
此内容受MIT许可协议的许可。双重许可真的很烦人,我也不理解其合理性。如果您真的需要Apache许可,只需向我提出,我会为您解决。
依赖项
~410KB