2个版本
0.1.1 | 2020年9月24日 |
---|---|
0.1.0 | 2020年9月23日 |
#1999 in 加密学
24KB
120 行
bronco
Bronco提供认证和加密的API令牌。
基于Branca规范(略有修改),此模块提供认证和加密的API令牌。加密原语由libsodium通过sodiumoxide
库提供。
IETF XChaCha20-Poly1305 AEAD对称加密用于创建令牌。加密令牌使用url-safe Base64变种(无填充)进行base64编码。Branca使用Base62来确保URL安全性,但由于url-safe Base64编码的URL安全变种更常见,我们使用它。
安全保证
我提供绝对没有任何安全保证。
我不是密码学家。这不是经过审计的实现。这并不完全遵循Branca规范。
这是一个我写的库,以便更好地理解AEAD原语和认证/加密API令牌。我确实在我的项目pasta6中使用它,充分了解我可能犯了一些简单的错误。
示例
将bronco
和sodiumoxide
添加到依赖项
bronco = "0.1.1"
sodiumoxide = "0.2.6"
编码
use bronco::encode;
use sodiumoxide::crypto::aead::xchacha20poly1305_ietf::gen_key;
sodiumoxide::init();
let key = gen_key();
let message: &str = "hello, world!";
let token: String = encode(message, key.as_ref()).unwrap();
解码
use bronco::decode;
// let token: &str = ...;
// let key: &[u8] = ...;
let ttl: u32 = 60; // token is valid for 1 minute
let message = decode(token, key, ttl).unwrap();
assert_eq!(message, "hello, world!");
令牌格式
令牌包含一个头部、密文和认证标签。头部包含版本、时间戳和nonce。总体令牌结构为
Version (1B) || Timestamp (4B) || Nonce (24B) || Ciphertext (*B) || Tag (16B)
密文可以任意长,其长度将与明文消息的长度完全相同。
二进制令牌的字符串表示使用Base64 (URL-safe variant)编码,使用以下字符集
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_
更多详细信息请参阅Branca规范。
密钥
密钥必须为32字节长。任何32字节切片都可以用作密钥,但强烈建议您使用sodiumoxide的sodiumoxide::crypto::aead::xchacha20poly1305_ietf::gen_key
函数生成真正的随机密钥。
实现细节
本模块与Branca规范相比,有几个重大变化。
首先,二进制令牌使用Base64(URL安全变体)编码为字符串,而不是Base62。
其次,假设令牌负载是有效的UTF-8。本模块只允许编码有效的UTF-8字符串,因此这不应该成为问题。自定义实现可能允许将任意字节编码到令牌中,因此为了处理非UTF-8负载,我们在解析负载时执行有损的UTF-8转换。无效的字符被UTF-8替换字符替换。
令牌强制执行TTL(生存时间),除非在解码时设置为0
。当一个令牌的时间戳比ttl
秒更早时,它被视为解码错误。无法指定无限TTL,但可以设置任意大的u32
值。
注意:当将TTL添加到UNIX纪元时间戳时,如果导致整数溢出,则将TTL视为无效。
许可证:GPL-3.0或更高版本
依赖项
~18MB
~81K SLoC