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::{
10    AsymmetricCipher, Hasher, KeyDerivation, KeyEncapsulation, PasswordBasedKdf, SymmetricCipher,
11};
12use crate::error::{Error, Result};
13use crate::registry::Registry;
14
15mod asymmetric;
16pub use asymmetric::{KeyAgreementManager, SignatureManager};
17
18/// 校验并设置默认标识。
19fn check_default(registry_has: bool, kind: &'static str, identifier: &str) -> Result<()> {
20    if registry_has {
21        Ok(())
22    } else {
23        Err(Error::UnknownIdentifier {
24            kind,
25            identifier: identifier.to_string(),
26        })
27    }
28}
29
30/// 对称加密门面。
31#[derive(Debug)]
32pub struct EncryptionManager {
33    registry: Registry<Box<dyn SymmetricCipher>>,
34    default_identifier: String,
35}
36
37impl EncryptionManager {
38    /// `default_identifier` 必须已注册,否则返回 [`Error::UnknownIdentifier`]。
39    pub fn new(
40        registry: Registry<Box<dyn SymmetricCipher>>,
41        default_identifier: impl Into<String>,
42    ) -> Result<Self> {
43        let default_identifier = default_identifier.into();
44        check_default(
45            registry.has(&default_identifier),
46            registry_kind(),
47            &default_identifier,
48        )?;
49        Ok(Self {
50            registry,
51            default_identifier,
52        })
53    }
54
55    pub fn encrypt(&self, plaintext: &[u8]) -> Result<Vec<u8>> {
56        self.encrypt_with(&self.default_identifier, plaintext)
57    }
58
59    pub fn encrypt_with(&self, identifier: &str, plaintext: &[u8]) -> Result<Vec<u8>> {
60        self.registry.get(identifier)?.encrypt(plaintext)
61    }
62
63    pub fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>> {
64        self.decrypt_with(&self.default_identifier, ciphertext)
65    }
66
67    pub fn decrypt_with(&self, identifier: &str, ciphertext: &[u8]) -> Result<Vec<u8>> {
68        self.registry.get(identifier)?.decrypt(ciphertext)
69    }
70
71    pub fn registry(&self) -> &Registry<Box<dyn SymmetricCipher>> {
72        &self.registry
73    }
74
75    pub fn registry_mut(&mut self) -> &mut Registry<Box<dyn SymmetricCipher>> {
76        &mut self.registry
77    }
78
79    pub fn default_identifier(&self) -> &str {
80        &self.default_identifier
81    }
82
83    pub fn set_default_identifier(&mut self, identifier: impl Into<String>) -> Result<()> {
84        let identifier = identifier.into();
85        check_default(self.registry.has(&identifier), registry_kind(), &identifier)?;
86        self.default_identifier = identifier;
87        Ok(())
88    }
89}
90
91fn registry_kind() -> &'static str {
92    "symmetric cipher"
93}
94
95/// 非对称加密门面。
96#[derive(Debug)]
97pub struct AsymmetricCryptoManager {
98    registry: Registry<Box<dyn AsymmetricCipher>>,
99    default_identifier: String,
100}
101
102impl AsymmetricCryptoManager {
103    pub fn new(
104        registry: Registry<Box<dyn AsymmetricCipher>>,
105        default_identifier: impl Into<String>,
106    ) -> Result<Self> {
107        let default_identifier = default_identifier.into();
108        check_default(
109            registry.has(&default_identifier),
110            "asymmetric cipher",
111            &default_identifier,
112        )?;
113        Ok(Self {
114            registry,
115            default_identifier,
116        })
117    }
118
119    /// 返回十六进制密文。
120    pub fn encrypt(&self, plaintext: &[u8], public_key_hex: &str) -> Result<String> {
121        self.encrypt_with(&self.default_identifier, plaintext, public_key_hex)
122    }
123
124    pub fn encrypt_with(
125        &self,
126        identifier: &str,
127        plaintext: &[u8],
128        public_key_hex: &str,
129    ) -> Result<String> {
130        self.registry
131            .get(identifier)?
132            .encrypt(plaintext, public_key_hex)
133    }
134
135    pub fn decrypt(&self, ciphertext_hex: &str, private_key_hex: &str) -> Result<Vec<u8>> {
136        self.decrypt_with(&self.default_identifier, ciphertext_hex, private_key_hex)
137    }
138
139    pub fn decrypt_with(
140        &self,
141        identifier: &str,
142        ciphertext_hex: &str,
143        private_key_hex: &str,
144    ) -> Result<Vec<u8>> {
145        self.registry
146            .get(identifier)?
147            .decrypt(ciphertext_hex, private_key_hex)
148    }
149
150    pub fn registry(&self) -> &Registry<Box<dyn AsymmetricCipher>> {
151        &self.registry
152    }
153
154    pub fn registry_mut(&mut self) -> &mut Registry<Box<dyn AsymmetricCipher>> {
155        &mut self.registry
156    }
157
158    pub fn default_identifier(&self) -> &str {
159        &self.default_identifier
160    }
161
162    pub fn set_default_identifier(&mut self, identifier: impl Into<String>) -> Result<()> {
163        let identifier = identifier.into();
164        check_default(
165            self.registry.has(&identifier),
166            "asymmetric cipher",
167            &identifier,
168        )?;
169        self.default_identifier = identifier;
170        Ok(())
171    }
172}
173
174/// 哈希门面。
175#[derive(Debug)]
176pub struct HashingManager {
177    registry: Registry<Box<dyn Hasher>>,
178    default_identifier: String,
179}
180
181impl HashingManager {
182    pub fn new(
183        registry: Registry<Box<dyn Hasher>>,
184        default_identifier: impl Into<String>,
185    ) -> Result<Self> {
186        let default_identifier = default_identifier.into();
187        check_default(
188            registry.has(&default_identifier),
189            "hasher",
190            &default_identifier,
191        )?;
192        Ok(Self {
193            registry,
194            default_identifier,
195        })
196    }
197
198    pub fn digest(&self, data: &[u8]) -> Result<Vec<u8>> {
199        self.digest_with(&self.default_identifier, data)
200    }
201
202    pub fn digest_with(&self, identifier: &str, data: &[u8]) -> Result<Vec<u8>> {
203        self.registry.get(identifier)?.digest(data)
204    }
205
206    pub fn digest_hex(&self, data: &[u8]) -> Result<String> {
207        self.digest_hex_with(&self.default_identifier, data)
208    }
209
210    pub fn digest_hex_with(&self, identifier: &str, data: &[u8]) -> Result<String> {
211        self.registry.get(identifier)?.digest_hex(data)
212    }
213
214    pub fn registry(&self) -> &Registry<Box<dyn Hasher>> {
215        &self.registry
216    }
217
218    pub fn registry_mut(&mut self) -> &mut Registry<Box<dyn Hasher>> {
219        &mut self.registry
220    }
221
222    pub fn default_identifier(&self) -> &str {
223        &self.default_identifier
224    }
225
226    pub fn set_default_identifier(&mut self, identifier: impl Into<String>) -> Result<()> {
227        let identifier = identifier.into();
228        check_default(self.registry.has(&identifier), "hasher", &identifier)?;
229        self.default_identifier = identifier;
230        Ok(())
231    }
232}
233
234/// 密钥派生(HKDF)门面。
235#[derive(Debug)]
236pub struct KeyDerivationManager {
237    registry: Registry<Box<dyn KeyDerivation>>,
238    default_identifier: String,
239}
240
241impl KeyDerivationManager {
242    pub fn new(
243        registry: Registry<Box<dyn KeyDerivation>>,
244        default_identifier: impl Into<String>,
245    ) -> Result<Self> {
246        let default_identifier = default_identifier.into();
247        check_default(
248            registry.has(&default_identifier),
249            "key derivation",
250            &default_identifier,
251        )?;
252        Ok(Self {
253            registry,
254            default_identifier,
255        })
256    }
257
258    pub fn derive(&self, ikm: &[u8], salt: &[u8], length: usize, info: &[u8]) -> Result<Vec<u8>> {
259        self.derive_with(&self.default_identifier, ikm, salt, length, info)
260    }
261
262    pub fn derive_with(
263        &self,
264        identifier: &str,
265        ikm: &[u8],
266        salt: &[u8],
267        length: usize,
268        info: &[u8],
269    ) -> Result<Vec<u8>> {
270        self.registry
271            .get(identifier)?
272            .derive(ikm, salt, length, info)
273    }
274
275    pub fn registry(&self) -> &Registry<Box<dyn KeyDerivation>> {
276        &self.registry
277    }
278
279    pub fn registry_mut(&mut self) -> &mut Registry<Box<dyn KeyDerivation>> {
280        &mut self.registry
281    }
282
283    pub fn default_identifier(&self) -> &str {
284        &self.default_identifier
285    }
286
287    pub fn set_default_identifier(&mut self, identifier: impl Into<String>) -> Result<()> {
288        let identifier = identifier.into();
289        check_default(
290            self.registry.has(&identifier),
291            "key derivation",
292            &identifier,
293        )?;
294        self.default_identifier = identifier;
295        Ok(())
296    }
297}
298
299/// 口令派生(PBKDF2)门面。
300#[derive(Debug)]
301pub struct PasswordBasedKdfManager {
302    registry: Registry<Box<dyn PasswordBasedKdf>>,
303    default_identifier: String,
304}
305
306impl PasswordBasedKdfManager {
307    pub fn new(
308        registry: Registry<Box<dyn PasswordBasedKdf>>,
309        default_identifier: impl Into<String>,
310    ) -> Result<Self> {
311        let default_identifier = default_identifier.into();
312        check_default(
313            registry.has(&default_identifier),
314            "password-based kdf",
315            &default_identifier,
316        )?;
317        Ok(Self {
318            registry,
319            default_identifier,
320        })
321    }
322
323    pub fn derive_from_password(
324        &self,
325        password: &[u8],
326        salt: &[u8],
327        length: usize,
328    ) -> Result<Vec<u8>> {
329        self.derive_from_password_with(&self.default_identifier, password, salt, length)
330    }
331
332    pub fn derive_from_password_with(
333        &self,
334        identifier: &str,
335        password: &[u8],
336        salt: &[u8],
337        length: usize,
338    ) -> Result<Vec<u8>> {
339        self.registry
340            .get(identifier)?
341            .derive_from_password(password, salt, length)
342    }
343
344    pub fn registry(&self) -> &Registry<Box<dyn PasswordBasedKdf>> {
345        &self.registry
346    }
347
348    pub fn registry_mut(&mut self) -> &mut Registry<Box<dyn PasswordBasedKdf>> {
349        &mut self.registry
350    }
351
352    pub fn default_identifier(&self) -> &str {
353        &self.default_identifier
354    }
355
356    pub fn set_default_identifier(&mut self, identifier: impl Into<String>) -> Result<()> {
357        let identifier = identifier.into();
358        check_default(
359            self.registry.has(&identifier),
360            "password-based kdf",
361            &identifier,
362        )?;
363        self.default_identifier = identifier;
364        Ok(())
365    }
366}
367
368/// 密钥封装(KEM)门面。
369#[derive(Debug)]
370pub struct KeyEncapsulationManager {
371    registry: Registry<Box<dyn KeyEncapsulation>>,
372    default_identifier: String,
373}
374
375impl KeyEncapsulationManager {
376    pub fn new(
377        registry: Registry<Box<dyn KeyEncapsulation>>,
378        default_identifier: impl Into<String>,
379    ) -> Result<Self> {
380        let default_identifier = default_identifier.into();
381        check_default(
382            registry.has(&default_identifier),
383            "key encapsulation",
384            &default_identifier,
385        )?;
386        Ok(Self {
387            registry,
388            default_identifier,
389        })
390    }
391
392    /// 生成密钥对,返回 `(公钥 hex, 私钥 hex)`。
393    pub fn generate(&self) -> Result<(String, String)> {
394        self.generate_with(&self.default_identifier)
395    }
396
397    pub fn generate_with(&self, identifier: &str) -> Result<(String, String)> {
398        self.registry.get(identifier)?.generate()
399    }
400
401    /// 用公钥封装,返回 `(密文 hex, 共享密钥 hex)`。
402    pub fn encapsulate(&self, public_key_hex: &str) -> Result<(String, String)> {
403        self.encapsulate_with(&self.default_identifier, public_key_hex)
404    }
405
406    pub fn encapsulate_with(
407        &self,
408        identifier: &str,
409        public_key_hex: &str,
410    ) -> Result<(String, String)> {
411        self.registry.get(identifier)?.encapsulate(public_key_hex)
412    }
413
414    /// 用私钥解封装,返回共享密钥 hex(非法密文按隐式拒绝语义不报错)。
415    pub fn decapsulate(&self, ciphertext_hex: &str, private_key_hex: &str) -> Result<String> {
416        self.decapsulate_with(&self.default_identifier, ciphertext_hex, private_key_hex)
417    }
418
419    pub fn decapsulate_with(
420        &self,
421        identifier: &str,
422        ciphertext_hex: &str,
423        private_key_hex: &str,
424    ) -> Result<String> {
425        self.registry
426            .get(identifier)?
427            .decapsulate(ciphertext_hex, private_key_hex)
428    }
429
430    pub fn registry(&self) -> &Registry<Box<dyn KeyEncapsulation>> {
431        &self.registry
432    }
433
434    pub fn registry_mut(&mut self) -> &mut Registry<Box<dyn KeyEncapsulation>> {
435        &mut self.registry
436    }
437
438    pub fn default_identifier(&self) -> &str {
439        &self.default_identifier
440    }
441
442    pub fn set_default_identifier(&mut self, identifier: impl Into<String>) -> Result<()> {
443        let identifier = identifier.into();
444        check_default(
445            self.registry.has(&identifier),
446            "key encapsulation",
447            &identifier,
448        )?;
449        self.default_identifier = identifier;
450        Ok(())
451    }
452}