Skip to main content

encryption/
manager.rs

1// Copyright (c) 2026 erik <erik@erik.xyz> — https://erik.xyz
2
3//! 门面(Manager):注册表 + 默认标识的组合,业务层的常用入口。
4//!
5//! 对应 PHP 版的 `EncryptionManager`、`AsymmetricCryptoManager`、`HashingManager`、
6//! `KeyDerivationManager`、`PasswordBasedKdfManager`。每个门面提供「用默认算法」与
7//! 「显式指定 `*_with(identifier, ...)`」两组方法。
8
9use crate::contract::{AsymmetricCipher, Hasher, KeyDerivation, PasswordBasedKdf, SymmetricCipher};
10use crate::error::{Error, Result};
11use crate::registry::Registry;
12
13/// 校验并设置默认标识。
14fn check_default(registry_has: bool, kind: &'static str, identifier: &str) -> Result<()> {
15    if registry_has {
16        Ok(())
17    } else {
18        Err(Error::UnknownIdentifier {
19            kind,
20            identifier: identifier.to_string(),
21        })
22    }
23}
24
25/// 对称加密门面。
26#[derive(Debug)]
27pub struct EncryptionManager {
28    registry: Registry<Box<dyn SymmetricCipher>>,
29    default_identifier: String,
30}
31
32impl EncryptionManager {
33    /// `default_identifier` 必须已注册,否则返回 [`Error::UnknownIdentifier`]。
34    pub fn new(
35        registry: Registry<Box<dyn SymmetricCipher>>,
36        default_identifier: impl Into<String>,
37    ) -> Result<Self> {
38        let default_identifier = default_identifier.into();
39        check_default(
40            registry.has(&default_identifier),
41            registry_kind(),
42            &default_identifier,
43        )?;
44        Ok(Self {
45            registry,
46            default_identifier,
47        })
48    }
49
50    pub fn encrypt(&self, plaintext: &[u8]) -> Result<Vec<u8>> {
51        self.encrypt_with(&self.default_identifier, plaintext)
52    }
53
54    pub fn encrypt_with(&self, identifier: &str, plaintext: &[u8]) -> Result<Vec<u8>> {
55        self.registry.get(identifier)?.encrypt(plaintext)
56    }
57
58    pub fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>> {
59        self.decrypt_with(&self.default_identifier, ciphertext)
60    }
61
62    pub fn decrypt_with(&self, identifier: &str, ciphertext: &[u8]) -> Result<Vec<u8>> {
63        self.registry.get(identifier)?.decrypt(ciphertext)
64    }
65
66    pub fn registry(&self) -> &Registry<Box<dyn SymmetricCipher>> {
67        &self.registry
68    }
69
70    pub fn registry_mut(&mut self) -> &mut Registry<Box<dyn SymmetricCipher>> {
71        &mut self.registry
72    }
73
74    pub fn default_identifier(&self) -> &str {
75        &self.default_identifier
76    }
77
78    pub fn set_default_identifier(&mut self, identifier: impl Into<String>) -> Result<()> {
79        let identifier = identifier.into();
80        check_default(self.registry.has(&identifier), registry_kind(), &identifier)?;
81        self.default_identifier = identifier;
82        Ok(())
83    }
84}
85
86fn registry_kind() -> &'static str {
87    "symmetric cipher"
88}
89
90/// 非对称加密门面。
91#[derive(Debug)]
92pub struct AsymmetricCryptoManager {
93    registry: Registry<Box<dyn AsymmetricCipher>>,
94    default_identifier: String,
95}
96
97impl AsymmetricCryptoManager {
98    pub fn new(
99        registry: Registry<Box<dyn AsymmetricCipher>>,
100        default_identifier: impl Into<String>,
101    ) -> Result<Self> {
102        let default_identifier = default_identifier.into();
103        check_default(
104            registry.has(&default_identifier),
105            "asymmetric cipher",
106            &default_identifier,
107        )?;
108        Ok(Self {
109            registry,
110            default_identifier,
111        })
112    }
113
114    /// 返回十六进制密文。
115    pub fn encrypt(&self, plaintext: &[u8], public_key_hex: &str) -> Result<String> {
116        self.encrypt_with(&self.default_identifier, plaintext, public_key_hex)
117    }
118
119    pub fn encrypt_with(
120        &self,
121        identifier: &str,
122        plaintext: &[u8],
123        public_key_hex: &str,
124    ) -> Result<String> {
125        self.registry
126            .get(identifier)?
127            .encrypt(plaintext, public_key_hex)
128    }
129
130    pub fn decrypt(&self, ciphertext_hex: &str, private_key_hex: &str) -> Result<Vec<u8>> {
131        self.decrypt_with(&self.default_identifier, ciphertext_hex, private_key_hex)
132    }
133
134    pub fn decrypt_with(
135        &self,
136        identifier: &str,
137        ciphertext_hex: &str,
138        private_key_hex: &str,
139    ) -> Result<Vec<u8>> {
140        self.registry
141            .get(identifier)?
142            .decrypt(ciphertext_hex, private_key_hex)
143    }
144
145    pub fn registry(&self) -> &Registry<Box<dyn AsymmetricCipher>> {
146        &self.registry
147    }
148
149    pub fn registry_mut(&mut self) -> &mut Registry<Box<dyn AsymmetricCipher>> {
150        &mut self.registry
151    }
152
153    pub fn default_identifier(&self) -> &str {
154        &self.default_identifier
155    }
156
157    pub fn set_default_identifier(&mut self, identifier: impl Into<String>) -> Result<()> {
158        let identifier = identifier.into();
159        check_default(
160            self.registry.has(&identifier),
161            "asymmetric cipher",
162            &identifier,
163        )?;
164        self.default_identifier = identifier;
165        Ok(())
166    }
167}
168
169/// 哈希门面。
170#[derive(Debug)]
171pub struct HashingManager {
172    registry: Registry<Box<dyn Hasher>>,
173    default_identifier: String,
174}
175
176impl HashingManager {
177    pub fn new(
178        registry: Registry<Box<dyn Hasher>>,
179        default_identifier: impl Into<String>,
180    ) -> Result<Self> {
181        let default_identifier = default_identifier.into();
182        check_default(
183            registry.has(&default_identifier),
184            "hasher",
185            &default_identifier,
186        )?;
187        Ok(Self {
188            registry,
189            default_identifier,
190        })
191    }
192
193    pub fn digest(&self, data: &[u8]) -> Result<Vec<u8>> {
194        self.digest_with(&self.default_identifier, data)
195    }
196
197    pub fn digest_with(&self, identifier: &str, data: &[u8]) -> Result<Vec<u8>> {
198        self.registry.get(identifier)?.digest(data)
199    }
200
201    pub fn digest_hex(&self, data: &[u8]) -> Result<String> {
202        self.digest_hex_with(&self.default_identifier, data)
203    }
204
205    pub fn digest_hex_with(&self, identifier: &str, data: &[u8]) -> Result<String> {
206        self.registry.get(identifier)?.digest_hex(data)
207    }
208
209    pub fn registry(&self) -> &Registry<Box<dyn Hasher>> {
210        &self.registry
211    }
212
213    pub fn registry_mut(&mut self) -> &mut Registry<Box<dyn Hasher>> {
214        &mut self.registry
215    }
216
217    pub fn default_identifier(&self) -> &str {
218        &self.default_identifier
219    }
220
221    pub fn set_default_identifier(&mut self, identifier: impl Into<String>) -> Result<()> {
222        let identifier = identifier.into();
223        check_default(self.registry.has(&identifier), "hasher", &identifier)?;
224        self.default_identifier = identifier;
225        Ok(())
226    }
227}
228
229/// 密钥派生(HKDF)门面。
230#[derive(Debug)]
231pub struct KeyDerivationManager {
232    registry: Registry<Box<dyn KeyDerivation>>,
233    default_identifier: String,
234}
235
236impl KeyDerivationManager {
237    pub fn new(
238        registry: Registry<Box<dyn KeyDerivation>>,
239        default_identifier: impl Into<String>,
240    ) -> Result<Self> {
241        let default_identifier = default_identifier.into();
242        check_default(
243            registry.has(&default_identifier),
244            "key derivation",
245            &default_identifier,
246        )?;
247        Ok(Self {
248            registry,
249            default_identifier,
250        })
251    }
252
253    pub fn derive(&self, ikm: &[u8], salt: &[u8], length: usize, info: &[u8]) -> Result<Vec<u8>> {
254        self.derive_with(&self.default_identifier, ikm, salt, length, info)
255    }
256
257    pub fn derive_with(
258        &self,
259        identifier: &str,
260        ikm: &[u8],
261        salt: &[u8],
262        length: usize,
263        info: &[u8],
264    ) -> Result<Vec<u8>> {
265        self.registry
266            .get(identifier)?
267            .derive(ikm, salt, length, info)
268    }
269
270    pub fn registry(&self) -> &Registry<Box<dyn KeyDerivation>> {
271        &self.registry
272    }
273
274    pub fn registry_mut(&mut self) -> &mut Registry<Box<dyn KeyDerivation>> {
275        &mut self.registry
276    }
277
278    pub fn default_identifier(&self) -> &str {
279        &self.default_identifier
280    }
281
282    pub fn set_default_identifier(&mut self, identifier: impl Into<String>) -> Result<()> {
283        let identifier = identifier.into();
284        check_default(
285            self.registry.has(&identifier),
286            "key derivation",
287            &identifier,
288        )?;
289        self.default_identifier = identifier;
290        Ok(())
291    }
292}
293
294/// 口令派生(PBKDF2)门面。
295#[derive(Debug)]
296pub struct PasswordBasedKdfManager {
297    registry: Registry<Box<dyn PasswordBasedKdf>>,
298    default_identifier: String,
299}
300
301impl PasswordBasedKdfManager {
302    pub fn new(
303        registry: Registry<Box<dyn PasswordBasedKdf>>,
304        default_identifier: impl Into<String>,
305    ) -> Result<Self> {
306        let default_identifier = default_identifier.into();
307        check_default(
308            registry.has(&default_identifier),
309            "password-based kdf",
310            &default_identifier,
311        )?;
312        Ok(Self {
313            registry,
314            default_identifier,
315        })
316    }
317
318    pub fn derive_from_password(
319        &self,
320        password: &[u8],
321        salt: &[u8],
322        length: usize,
323    ) -> Result<Vec<u8>> {
324        self.derive_from_password_with(&self.default_identifier, password, salt, length)
325    }
326
327    pub fn derive_from_password_with(
328        &self,
329        identifier: &str,
330        password: &[u8],
331        salt: &[u8],
332        length: usize,
333    ) -> Result<Vec<u8>> {
334        self.registry
335            .get(identifier)?
336            .derive_from_password(password, salt, length)
337    }
338
339    pub fn registry(&self) -> &Registry<Box<dyn PasswordBasedKdf>> {
340        &self.registry
341    }
342
343    pub fn registry_mut(&mut self) -> &mut Registry<Box<dyn PasswordBasedKdf>> {
344        &mut self.registry
345    }
346
347    pub fn default_identifier(&self) -> &str {
348        &self.default_identifier
349    }
350
351    pub fn set_default_identifier(&mut self, identifier: impl Into<String>) -> Result<()> {
352        let identifier = identifier.into();
353        check_default(
354            self.registry.has(&identifier),
355            "password-based kdf",
356            &identifier,
357        )?;
358        self.default_identifier = identifier;
359        Ok(())
360    }
361}