#hmac #jwt #signing #serialiser #itsdangerous

hmac-serialiser

HMAC 序列化程序,用于加密签名数据,类似于Python的 ItsDangerous 库,但使用 Rust 实现

3 个不稳定版本

0.3.1 2024年6月27日
0.3.0 2024年6月27日
0.2.0 2024年6月21日

加密学 中排名第1022

每月下载次数31

MIT 许可证

26KB
279

hmac-serialiser

Crates.io version shield License: MIT

HMAC 序列化程序,用于加密签名数据,类似于Python的 ItsDangerous 库,但使用 Rust 实现。

此库主要面向希望得到比JSON Web Tokens (JWT)更短的签名数据的开发者,因为JWT的数据可能太长,不适合他们的用例。

此 HMAC 序列化程序灵感来源于Python的 ItsDangerous 库,并生成一个类似于 <payload>.<signature> 的输出结构,而JWT则生成 <header>.<payload>.<signature>

为什么省略了头信息?头信息通常包含有关签名时使用的算法等信息。相反,这项责任被放在了开发者的手中。因此,不需要存储有关验证签名数据时使用的算法的头信息。

此外,HMAC 算法中使用的关键字通过 HKDF 扩展来解决关键字重用问题,通过从原始关键字、盐和一个可选的信息中派生关键字。此外,扩展的关键字被扩展到HMAC算法中使用的散列函数输出大小的长度,以避免关键字填充,从而减少暴力破解的努力。

关于加密实现,您可以通过 features 标志在 Cargo.toml 文件中选择要使用的实现

  • rust_crypto (默认)
    • 底层的 SHA1、SHA2、HMAC 和 HKDF 实现由 RustCrypto 提供。
  • ring
    • 底层的 SHA1、SHA2、HMAC 和 HKDF 实现来自 ring 包。

此外,数据序列化和反序列化使用 serde 包,然后使用 base64 包对签名数据进行编码或解码。

示例用法

use hmac_serialiser::{Encoder, HmacSigner, KeyInfo, Payload, Algorithm};
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct UserData {
    // Add your data fields here
    username: String,
    email: String,
}

impl Payload for UserData {
    fn get_exp(&self) -> Option<chrono::DateTime<chrono::Utc>> {
        // Add logic to retrieve expiration time if needed
        None
    }
}

fn main() {
    // Define your secret key, salt, and optional info
    let key_info = KeyInfo {
        key: b"your_secret_key".to_vec(),
        salt: b"your_salt".to_vec(),
        info: vec![], // empty info
    };

    // Initialize the HMAC signer
    let signer = HmacSigner::new(key_info, Algorithm::SHA256, Encoder::UrlSafeNoPadding);

    // Serialize your data
    let user_data = UserData {
        username: "user123".to_string(),
        email: "[email protected]".to_string(),
    };

    // Sign the data (safe to use by clients)
    let token = signer.sign(&user_data);
    println!("Token: {}", token);
    
    // Verify the token given by the client
    let verified_data: UserData = signer.unsign(&token)
        .expect("Failed to verify token");
    println!("Verified data: {:?}", verified_data);
}

依赖项

~2–11MB
~140K SLoC