2个版本

0.1.1 2020年9月24日
0.1.0 2020年9月23日

#1999 in 加密学

GPL-3.0-or-later

24KB
120

bronco

cargo-downloads-badge api-docs-badge crates-io license-badge

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中使用它,充分了解我可能犯了一些简单的错误。

示例

broncosodiumoxide添加到依赖项

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