Skip to main content

encryption/
contract.rs

1// Copyright (c) 2026 erik <erik@erik.xyz> — https://erik.xyz
2
3//! 能力契约(trait):业务层唯一需要依赖的东西。
4//!
5//! 对应 PHP 版的 `Contract/` 命名空间。PHP 里 `EncryptorInterface` 是
6//! `SymmetricCipherInterface` 的别名,Rust 侧只保留一个 [`SymmetricCipher`]。
7
8use crate::error::Result;
9
10/// 任何可注册进注册表的能力都带一个稳定标识(如 `aes-256-gcm`)。
11pub trait Identified {
12    fn identifier(&self) -> &str;
13}
14
15impl<T: Identified + ?Sized> Identified for Box<T> {
16    fn identifier(&self) -> &str {
17        (**self).identifier()
18    }
19}
20
21/// 对称加密:同一实例绑定固定密钥,对二进制载荷加解密。
22pub trait SymmetricCipher: Identified + Send + Sync {
23    fn encrypt(&self, plaintext: &[u8]) -> Result<Vec<u8>>;
24
25    fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>>;
26}
27
28/// 非对称加密:每次调用传入密钥材料(十六进制,格式由实现决定,如 SM2)。
29pub trait AsymmetricCipher: Identified + Send + Sync {
30    /// 返回十六进制密文。
31    fn encrypt(&self, plaintext: &[u8], public_key_hex: &str) -> Result<String>;
32
33    fn decrypt(&self, ciphertext_hex: &str, private_key_hex: &str) -> Result<Vec<u8>>;
34}
35
36/// 哈希:单向摘要,无密钥。
37pub trait Hasher: Identified + Send + Sync {
38    fn digest(&self, data: &[u8]) -> Result<Vec<u8>>;
39
40    /// 十六进制摘要;实现只需要实现 [`Hasher::digest`]。
41    fn digest_hex(&self, data: &[u8]) -> Result<String> {
42        Ok(crate::internal::hex_encode(&self.digest(data)?))
43    }
44}
45
46/// 基于密钥材料的派生(典型为 HKDF):从 IKM + salt + info 得到任意长度输出。
47pub trait KeyDerivation: Identified + Send + Sync {
48    /// `ikm`:输入密钥材料(如主密钥、DH 共享秘密);
49    /// `salt`:盐值(可为空,但建议非空随机);
50    /// `info`:可选上下文信息(如协议标签)。
51    fn derive(&self, ikm: &[u8], salt: &[u8], length: usize, info: &[u8]) -> Result<Vec<u8>>;
52}
53
54/// 基于口令的密钥派生(典型为 PBKDF2):从人类可读口令得到固定长度密钥。
55pub trait PasswordBasedKdf: Identified + Send + Sync {
56    /// `salt`:随机盐(建议每用户 / 每密钥唯一)。
57    fn derive_from_password(&self, password: &[u8], salt: &[u8], length: usize) -> Result<Vec<u8>>;
58}