Skip to main content

sz_orm_crypto/
lib.rs

1//! # SZ-ORM Crypto — 加密工具
2//!
3//! 提供常用密码学原语:AES-256-GCM 对称加密、HMAC-SHA256 消息认证码、
4//! PBKDF2 密钥派生与 SHA-256 哈希,所有实现基于 RustCrypto,保证常数时间比较。
5//!
6//! ## 主要函数
7//!
8//! - [`sha256`] / [`sha256_hex`] — SHA-256 哈希
9//! - AES-256-GCM 加解密
10//! - HMAC-SHA256 与 PBKDF2
11
12pub mod key_management;
13
14use std::collections::HashMap;
15
16use aes_gcm::aead::{Aead, KeyInit};
17use aes_gcm::{Aes256Gcm, Key, Nonce};
18use hmac::{Hmac, Mac};
19use pbkdf2::pbkdf2_hmac;
20use rand::rngs::OsRng;
21use rand::RngCore;
22use sha2::{Digest, Sha256};
23use subtle::ConstantTimeEq;
24
25type HmacSha256 = Hmac<Sha256>;
26
27// ============================================================================
28// SHA-256 (基于 RustCrypto sha2 crate, FIPS 180-4)
29// ============================================================================
30
31/// Compute the SHA-256 hash (based on RustCrypto sha2).
32pub fn sha256(data: &[u8]) -> [u8; 32] {
33    let mut hasher = Sha256::new();
34    hasher.update(data);
35    let result = hasher.finalize();
36    let mut out = [0u8; 32];
37    out.copy_from_slice(&result);
38    out
39}
40
41/// Compute SHA-256 and return the result as a hexadecimal string.
42pub fn sha256_hex(data: &[u8]) -> String {
43    sha256(data).iter().map(|b| format!("{:02x}", b)).collect()
44}
45
46/// HMAC-SHA256 (RFC 2104, based on RustCrypto hmac crate).
47pub fn hmac_sha256(key: &[u8], message: &[u8]) -> [u8; 32] {
48    // HMAC-SHA256 按 RFC 2104 接受任意长度 key,RustCrypto 的 new_from_slice 对 HMAC 永远返回 Ok。
49    // 用 match 处理避免 panic,虽然 Err 分支不可达(RustCrypto 不变量保证)。
50    let mut mac = match <HmacSha256 as Mac>::new_from_slice(key) {
51        Ok(m) => m,
52        Err(_) => {
53            // 不可达分支:HMAC 规范允许任意 key 长度,RustCrypto 内部会先 hash 过长 key。
54            // 为安全起见返回全零(调用方在正常路径下永远不会命中此分支)。
55            return [0u8; 32];
56        }
57    };
58    mac.update(message);
59    let result = mac.finalize().into_bytes();
60    let mut out = [0u8; 32];
61    out.copy_from_slice(&result);
62    out
63}
64
65/// HMAC-SHA256 hexadecimal string.
66pub fn hmac_sha256_hex(key: &[u8], message: &[u8]) -> String {
67    hmac_sha256(key, message)
68        .iter()
69        .map(|b| format!("{:02x}", b))
70        .collect()
71}
72
73/// Constant-time comparison (based on the subtle crate) to avoid timing attacks.
74fn constant_time_eq(a: &[u8], b: &[u8]) -> bool {
75    a.ct_eq(b).into()
76}
77
78// ============================================================================
79// 加密器
80// ============================================================================
81
82pub trait Crypter: Send + Sync {
83    fn encrypt(&self, plaintext: &[u8]) -> Result<Vec<u8>, CryptoError>;
84    fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, CryptoError>;
85}
86
87/// AES-256-GCM crypter (cryptographically secure).
88///
89/// Uses the AES-256-GCM AEAD algorithm and generates a random 12-byte nonce on
90/// each encryption. Ciphertext format: `nonce(12) || ciphertext || tag(16)`
91/// (handled internally by the aes-gcm crate).
92pub struct AesGcmCrypter {
93    cipher: Aes256Gcm,
94}
95
96impl AesGcmCrypter {
97    /// Create from a 32-byte key.
98    pub fn new(key: &[u8; 32]) -> Self {
99        let key = Key::<Aes256Gcm>::from_slice(key);
100        Self {
101            cipher: Aes256Gcm::new(key),
102        }
103    }
104
105    /// Create from a key string of arbitrary length (derives a 32-byte key via SHA-256).
106    pub fn from_key_str(key: &str) -> Self {
107        let hash = sha256(key.as_bytes());
108        Self::new(&hash)
109    }
110
111    fn random_nonce() -> [u8; 12] {
112        let mut nonce = [0u8; 12];
113        OsRng.fill_bytes(&mut nonce);
114        nonce
115    }
116}
117
118impl Crypter for AesGcmCrypter {
119    fn encrypt(&self, plaintext: &[u8]) -> Result<Vec<u8>, CryptoError> {
120        self.encrypt_with_aad(plaintext, &[])
121    }
122
123    fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, CryptoError> {
124        self.decrypt_with_aad(ciphertext, &[])
125    }
126}
127
128impl AesGcmCrypter {
129    /// AES-GCM authenticated encryption (with Additional Authenticated Data, AAD).
130    ///
131    /// Ciphertext format: `nonce(12) || ciphertext || tag(16)`.
132    /// AAD (Additional Authenticated Data) is not included in the ciphertext but
133    /// participates in the authentication tag computation; the same AAD must be
134    /// provided during decryption to succeed.
135    pub fn encrypt_with_aad(&self, plaintext: &[u8], aad: &[u8]) -> Result<Vec<u8>, CryptoError> {
136        let nonce_bytes = Self::random_nonce();
137        let nonce = Nonce::from_slice(&nonce_bytes);
138        let payload = aes_gcm::aead::Payload {
139            msg: plaintext,
140            aad,
141        };
142        let ciphertext = self
143            .cipher
144            .encrypt(nonce, payload)
145            .map_err(|e| CryptoError::EncryptionFailed(e.to_string()))?;
146        let mut result = Vec::with_capacity(12 + ciphertext.len());
147        result.extend_from_slice(&nonce_bytes);
148        result.extend_from_slice(&ciphertext);
149        Ok(result)
150    }
151
152    /// AES-GCM authenticated decryption (with Additional Authenticated Data, AAD).
153    ///
154    /// The same AAD used during encryption must be provided, otherwise the
155    /// authentication tag verification fails.
156    pub fn decrypt_with_aad(&self, ciphertext: &[u8], aad: &[u8]) -> Result<Vec<u8>, CryptoError> {
157        if ciphertext.len() < 12 {
158            return Err(CryptoError::DecryptionFailed(
159                "Ciphertext too short".to_string(),
160            ));
161        }
162        let nonce = Nonce::from_slice(&ciphertext[..12]);
163        let encrypted = &ciphertext[12..];
164        let payload = aes_gcm::aead::Payload {
165            msg: encrypted,
166            aad,
167        };
168        self.cipher
169            .decrypt(nonce, payload)
170            .map_err(|e| CryptoError::DecryptionFailed(e.to_string()))
171    }
172}
173
174// ============================================================================
175// 密码哈希
176// ============================================================================
177
178pub trait PasswordHasher: Send + Sync {
179    fn hash(&self, password: &str) -> Result<String, CryptoError>;
180    fn verify(&self, password: &str, hash: &str) -> Result<bool, CryptoError>;
181}
182
183/// PBKDF2-HMAC-SHA256 password hasher (based on RustCrypto pbkdf2 crate).
184///
185/// Uses the PBKDF2-HMAC-SHA256 algorithm (RFC 8018).
186/// Hash format: `$<iterations>$<salt_hex>$<hash_hex>`
187pub struct Pbkdf2Hasher {
188    iterations: u32,
189}
190
191impl Pbkdf2Hasher {
192    const DEFAULT_ITERATIONS: u32 = 100_000;
193    const SALT_LEN: usize = 16;
194    const HASH_LEN: usize = 32;
195
196    pub fn new() -> Self {
197        Self {
198            iterations: Self::DEFAULT_ITERATIONS,
199        }
200    }
201
202    pub fn with_iterations(iterations: u32) -> Self {
203        Self {
204            iterations: iterations.max(1),
205        }
206    }
207
208    /// Iteration count upper and lower bounds (v4.8.0 fix for M-8):
209    /// - The lower bound aligns with the production default and rejects weak hashes
210    ///   with c<100_000 (black-hat demo showed c=1 was accepted).
211    /// - The upper bound prevents `$4294967295$...` CPU DoS (a single verify could
212    ///   stall for minutes).
213    pub const MIN_ITERATIONS: u32 = 100_000;
214    pub const MAX_ITERATIONS: u32 = 10_000_000;
215
216    fn compute_hash(password: &str, salt: &[u8], iterations: u32) -> [u8; Self::HASH_LEN] {
217        let mut out = [0u8; Self::HASH_LEN];
218        pbkdf2_hmac::<Sha256>(password.as_bytes(), salt, iterations, &mut out);
219        out
220    }
221}
222
223impl Default for Pbkdf2Hasher {
224    fn default() -> Self {
225        Self::new()
226    }
227}
228
229impl PasswordHasher for Pbkdf2Hasher {
230    fn hash(&self, password: &str) -> Result<String, CryptoError> {
231        if password.is_empty() {
232            return Err(CryptoError::InvalidHash(
233                "Password cannot be empty".to_string(),
234            ));
235        }
236        // v4.8.0 修复 M-8:hash 侧同样拒绝低迭代配置(fail-fast,
237        // 避免生成无法通过 verify 门槛的哈希)
238        if self.iterations < Self::MIN_ITERATIONS {
239            return Err(CryptoError::InvalidHash(format!(
240                "Iterations below minimum ({} < {})",
241                self.iterations,
242                Self::MIN_ITERATIONS
243            )));
244        }
245        let salt = random_bytes(Self::SALT_LEN);
246        let hash = Self::compute_hash(password, &salt, self.iterations);
247        Ok(format!(
248            "${}${}${}",
249            self.iterations,
250            hex_encode(&salt),
251            hex_encode(&hash)
252        ))
253    }
254
255    fn verify(&self, password: &str, hash: &str) -> Result<bool, CryptoError> {
256        if !hash.starts_with('$') {
257            return Err(CryptoError::InvalidHash("Invalid hash format".to_string()));
258        }
259        let parts: Vec<&str> = hash[1..].splitn(3, '$').collect();
260        if parts.len() != 3 {
261            return Err(CryptoError::InvalidHash("Invalid hash format".to_string()));
262        }
263        let iterations: u32 = parts[0]
264            .parse()
265            .map_err(|_| CryptoError::InvalidHash("Invalid iterations".to_string()))?;
266
267        // v4.8.0 修复 M-8:迭代次数攻击者可控(来自存储串)——
268        // 无下限则弱哈希被接受(离线破解加速 10 万倍),无上限则 CPU DoS。
269        if iterations < Self::MIN_ITERATIONS {
270            return Err(CryptoError::InvalidHash(format!(
271                "Iterations below minimum ({iterations} < {})",
272                Self::MIN_ITERATIONS
273            )));
274        }
275        if iterations > Self::MAX_ITERATIONS {
276            return Err(CryptoError::InvalidHash(format!(
277                "Iterations above maximum ({iterations} > {})",
278                Self::MAX_ITERATIONS
279            )));
280        }
281
282        let salt = hex_decode(parts[1])
283            .map_err(|_| CryptoError::InvalidHash("Invalid salt hex".to_string()))?;
284        let expected_hash = hex_decode(parts[2])
285            .map_err(|_| CryptoError::InvalidHash("Invalid hash hex".to_string()))?;
286        let computed = Self::compute_hash(password, &salt, iterations);
287        Ok(constant_time_eq(&computed, &expected_hash))
288    }
289}
290
291// ============================================================================
292// API 签名
293// ============================================================================
294
295pub trait ApiSigner: Send + Sync {
296    fn sign(&self, params: &HashMap<String, String>, secret: &str) -> String;
297    fn verify(&self, params: &HashMap<String, String>, secret: &str, signature: &str) -> bool;
298}
299
300/// HMAC-SHA256 API signer.
301///
302/// Sorts parameters in lexicographic order, joins them into a query string, and
303/// then signs the result with HMAC-SHA256.
304///
305/// # Security notes (v4.8.0 fix for H-1 parameter smuggling)
306///
307/// - Both key and value are RFC 3986 percent-encoded before being joined,
308///   eliminating the canonical-string ambiguity between `{a:1,b:2}` and
309///   `{a:"1&b=2"}` (parameter smuggling).
310/// - **The caller must** include a timestamp/random nonce as one of the signed
311///   parameters and verify the time window on the server side; otherwise signed
312///   requests can still be replayed.
313pub struct HmacSigner;
314
315impl HmacSigner {
316    pub fn new() -> Self {
317        Self
318    }
319
320    /// RFC 3986 percent-encoding: keeps only unreserved characters
321    /// (ALPHA/DIGIT/-/./_/~); all other bytes are encoded as `%XX` uppercase
322    /// hexadecimal. Eliminates ambiguity of separators like `&` and `=`.
323    fn percent_encode(s: &str) -> String {
324        let mut out = String::with_capacity(s.len());
325        for b in s.bytes() {
326            match b {
327                b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'.' | b'_' | b'~' => {
328                    out.push(b as char)
329                }
330                _ => {
331                    out.push('%');
332                    out.push(
333                        char::from_digit((b >> 4) as u32, 16)
334                            .unwrap_or('0')
335                            .to_ascii_uppercase(),
336                    );
337                    out.push(
338                        char::from_digit((b & 0x0f) as u32, 16)
339                            .unwrap_or('0')
340                            .to_ascii_uppercase(),
341                    );
342                }
343            }
344        }
345        out
346    }
347
348    fn compute_signature(params: &HashMap<String, String>, secret: &str) -> String {
349        let mut sorted: Vec<_> = params.iter().collect();
350        sorted.sort_by(|a, b| a.0.cmp(b.0));
351
352        let query_string: String = sorted
353            .iter()
354            .map(|(k, v)| format!("{}={}", Self::percent_encode(k), Self::percent_encode(v)))
355            .collect::<Vec<_>>()
356            .join("&");
357
358        hmac_sha256_hex(secret.as_bytes(), query_string.as_bytes())
359    }
360}
361
362impl Default for HmacSigner {
363    fn default() -> Self {
364        Self::new()
365    }
366}
367
368impl ApiSigner for HmacSigner {
369    fn sign(&self, params: &HashMap<String, String>, secret: &str) -> String {
370        Self::compute_signature(params, secret)
371    }
372
373    fn verify(&self, params: &HashMap<String, String>, secret: &str, signature: &str) -> bool {
374        let computed = Self::compute_signature(params, secret);
375        constant_time_eq(computed.as_bytes(), signature.as_bytes())
376    }
377}
378
379// ============================================================================
380// RSA-OAEP 非对称加密
381// ============================================================================
382
383use rsa::oaep::Oaep;
384use rsa::{RsaPrivateKey, RsaPublicKey};
385use sha2::Sha256 as RsaSha256;
386
387/// RSA-OAEP asymmetric crypter (based on RustCrypto `rsa` crate).
388///
389/// Uses RSA-OAEP with SHA-256 and MGF1-SHA256 padding. Public key encrypts,
390/// private key decrypts; suitable for small data (e.g. key exchange, short
391/// message encryption).
392pub struct RsaOaepCrypter {
393    public_key: RsaPublicKey,
394    private_key: RsaPrivateKey,
395}
396
397impl RsaOaepCrypter {
398    /// Generate a new RSA key pair with the given bit length (2048 or 3072 recommended).
399    pub fn generate(key_bits: usize) -> Result<Self, CryptoError> {
400        let mut rng = OsRng;
401        let private_key = RsaPrivateKey::new(&mut rng, key_bits)
402            .map_err(|e| CryptoError::InvalidKey(e.to_string()))?;
403        let public_key = RsaPublicKey::from(&private_key);
404        Ok(Self {
405            public_key,
406            private_key,
407        })
408    }
409
410    /// Create from an existing key pair.
411    pub fn from_keys(public_key: RsaPublicKey, private_key: RsaPrivateKey) -> Self {
412        Self {
413            public_key,
414            private_key,
415        }
416    }
417
418    /// Return a reference to the public key.
419    pub fn public_key(&self) -> &RsaPublicKey {
420        &self.public_key
421    }
422
423    /// Return a reference to the private key.
424    pub fn private_key(&self) -> &RsaPrivateKey {
425        &self.private_key
426    }
427
428    /// Encrypt data with the public key (RSA-OAEP with SHA-256).
429    pub fn encrypt(&self, plaintext: &[u8]) -> Result<Vec<u8>, CryptoError> {
430        let mut rng = OsRng;
431        let padding = Oaep::new::<RsaSha256>();
432        self.public_key
433            .encrypt(&mut rng, padding, plaintext)
434            .map_err(|e| CryptoError::EncryptionFailed(e.to_string()))
435    }
436
437    /// Decrypt data with the private key (RSA-OAEP with SHA-256).
438    pub fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, CryptoError> {
439        let padding = Oaep::new::<RsaSha256>();
440        self.private_key
441            .decrypt(padding, ciphertext)
442            .map_err(|e| CryptoError::DecryptionFailed(e.to_string()))
443    }
444}
445
446impl Crypter for RsaOaepCrypter {
447    fn encrypt(&self, plaintext: &[u8]) -> Result<Vec<u8>, CryptoError> {
448        self.encrypt(plaintext)
449    }
450
451    fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, CryptoError> {
452        self.decrypt(ciphertext)
453    }
454}
455
456// ============================================================================
457// HMAC-SHA256 签名验证器
458// ============================================================================
459
460/// Signature verifier trait: provides message signing and verification interfaces.
461pub trait SignatureVerifier: Send + Sync {
462    /// Sign a message.
463    fn sign(&self, message: &[u8]) -> Vec<u8>;
464    /// Verify a message signature (constant-time comparison).
465    fn verify(&self, message: &[u8], signature: &[u8]) -> bool;
466}
467
468/// HMAC-SHA256 signature verifier.
469///
470/// Signs messages with HMAC-SHA256 and uses constant-time comparison during
471/// verification to prevent timing attacks.
472pub struct HmacSignatureVerifier {
473    key: Vec<u8>,
474}
475
476impl HmacSignatureVerifier {
477    /// Create a signature verifier, deriving from a key of arbitrary length.
478    pub fn new(key: &[u8]) -> Self {
479        Self { key: key.to_vec() }
480    }
481
482    /// Create from a string key.
483    pub fn from_key_str(key: &str) -> Self {
484        Self::new(key.as_bytes())
485    }
486}
487
488impl SignatureVerifier for HmacSignatureVerifier {
489    fn sign(&self, message: &[u8]) -> Vec<u8> {
490        hmac_sha256(&self.key, message).to_vec()
491    }
492
493    fn verify(&self, message: &[u8], signature: &[u8]) -> bool {
494        let expected = self.sign(message);
495        constant_time_eq(&expected, signature)
496    }
497}
498
499// ============================================================================
500// 密钥轮换(Key Rotation)
501// ============================================================================
502
503/// Key version: stores a key along with its version number and creation time.
504#[derive(Clone)]
505struct KeyVersion {
506    version: u32,
507    key: Vec<u8>,
508    created_at: u64,
509}
510
511/// Key rotation manager.
512///
513/// Manages multiple versions of keys and supports:
514/// - rotating to generate a new key version
515/// - signing with the latest key
516/// - verifying with any historical key (backward compatibility)
517/// - automatic eviction of expired keys
518pub struct KeyRotationManager {
519    keys: Vec<KeyVersion>,
520    current_version: u32,
521    max_versions: usize,
522}
523
524impl KeyRotationManager {
525    /// Create a key rotation manager with the specified maximum number of retained versions.
526    pub fn new(max_versions: usize) -> Self {
527        Self {
528            keys: vec![],
529            current_version: 0,
530            max_versions: max_versions.max(1),
531        }
532    }
533
534    /// Initialize with the first key version.
535    pub fn with_initial_key(key: Vec<u8>) -> Self {
536        let mut mgr = Self::new(3);
537        mgr.rotate_key(key);
538        mgr
539    }
540
541    /// Rotate to a new key and return the new version number.
542    pub fn rotate_key(&mut self, new_key: Vec<u8>) -> u32 {
543        self.current_version += 1;
544        let now = current_timestamp_secs();
545        self.keys.push(KeyVersion {
546            version: self.current_version,
547            key: new_key,
548            created_at: now,
549        });
550        // 淘汰过期版本
551        while self.keys.len() > self.max_versions {
552            self.keys.remove(0);
553        }
554        self.current_version
555    }
556
557    /// Sign with the current (latest) key.
558    pub fn sign(&self, message: &[u8]) -> (u32, Vec<u8>) {
559        if let Some(kv) = self.keys.last() {
560            let sig = hmac_sha256(&kv.key, message).to_vec();
561            (kv.version, sig)
562        } else {
563            (0, vec![])
564        }
565    }
566
567    /// Verify a signature (tries all retained key versions).
568    pub fn verify(&self, message: &[u8], version: u32, signature: &[u8]) -> bool {
569        for kv in &self.keys {
570            if kv.version == version {
571                let expected = hmac_sha256(&kv.key, message);
572                return constant_time_eq(&expected, signature);
573            }
574        }
575        false
576    }
577
578    /// Return the current key version number.
579    pub fn current_version(&self) -> u32 {
580        self.current_version
581    }
582
583    /// Return the number of retained key versions.
584    pub fn version_count(&self) -> usize {
585        self.keys.len()
586    }
587
588    /// Return all retained version numbers.
589    pub fn versions(&self) -> Vec<u32> {
590        self.keys.iter().map(|kv| kv.version).collect()
591    }
592
593    /// Return the creation time (Unix seconds) of the key for the specified
594    /// version, or `None` if the version does not exist.
595    pub fn key_created_at(&self, version: u32) -> Option<u64> {
596        self.keys
597            .iter()
598            .find(|kv| kv.version == version)
599            .map(|kv| kv.created_at)
600    }
601}
602
603fn current_timestamp_secs() -> u64 {
604    use std::time::{SystemTime, UNIX_EPOCH};
605    SystemTime::now()
606        .duration_since(UNIX_EPOCH)
607        .unwrap_or_default()
608        .as_secs()
609}
610
611// ============================================================================
612// 密钥版本管理与轮换(并发安全)
613// ============================================================================
614
615use std::sync::RwLock;
616use std::time::Duration;
617
618/// Default key rotation interval: 90 days.
619const DEFAULT_ROTATION_INTERVAL_SECS: u64 = 90 * 24 * 60 * 60;
620
621/// Versioned key.
622#[derive(Debug, Clone)]
623pub struct VersionedKey {
624    /// Key version.
625    pub version: u32,
626    /// Key bytes.
627    pub key: Vec<u8>,
628    /// Creation time.
629    pub created_at: std::time::SystemTime,
630}
631
632/// Key manager (supports rotation).
633///
634/// Maintains a current active key and at most 3 historical keys (for the
635/// decryption transition period), and supports automatic rotation checks at
636/// a fixed time interval. All fields are protected by `RwLock` and can be
637/// safely shared across threads.
638pub struct KeyManager {
639    /// Current active key.
640    current: RwLock<VersionedKey>,
641    /// List of old keys (for the decryption transition period).
642    previous: RwLock<Vec<VersionedKey>>,
643    /// Key rotation interval.
644    rotation_interval: Duration,
645    /// Last rotation time.
646    last_rotation: RwLock<std::time::SystemTime>,
647}
648
649impl KeyManager {
650    /// Create a key manager with the given initial key (version numbering starts at 1).
651    pub fn new(initial_key: Vec<u8>) -> Self {
652        let now = std::time::SystemTime::now();
653        Self {
654            current: RwLock::new(VersionedKey {
655                version: 1,
656                key: initial_key,
657                created_at: now,
658            }),
659            previous: RwLock::new(Vec::new()),
660            rotation_interval: Duration::from_secs(DEFAULT_ROTATION_INTERVAL_SECS),
661            last_rotation: RwLock::new(now),
662        }
663    }
664
665    /// Set the rotation interval.
666    pub fn with_rotation_interval(mut self, interval: Duration) -> Self {
667        self.rotation_interval = interval;
668        self
669    }
670
671    /// Rotate the key.
672    pub fn rotate(&self, new_key: Vec<u8>) -> Result<(), CryptoError> {
673        let mut current = self.current.write().expect("KeyManager lock poisoned");
674        let mut previous = self.previous.write().expect("KeyManager lock poisoned");
675
676        // 将当前密钥移入旧密钥列表
677        previous.push(current.clone());
678
679        // 保留最近 3 个旧密钥
680        if previous.len() > 3 {
681            previous.remove(0);
682        }
683
684        // 设置新密钥
685        *current = VersionedKey {
686            version: current.version + 1,
687            key: new_key,
688            created_at: std::time::SystemTime::now(),
689        };
690
691        *self
692            .last_rotation
693            .write()
694            .expect("KeyManager last_rotation lock poisoned") = std::time::SystemTime::now();
695        Ok(())
696    }
697
698    /// Check whether rotation is needed.
699    pub fn needs_rotation(&self) -> bool {
700        let last = *self
701            .last_rotation
702            .read()
703            .expect("KeyManager last_rotation lock poisoned");
704        std::time::SystemTime::now()
705            .duration_since(last)
706            .map(|d| d >= self.rotation_interval)
707            .unwrap_or(false)
708    }
709
710    /// Get the current key.
711    pub fn current_key(&self) -> VersionedKey {
712        self.current
713            .read()
714            .expect("KeyManager current lock poisoned")
715            .clone()
716    }
717
718    /// Look up a key by version.
719    pub fn key_by_version(&self, version: u32) -> Option<VersionedKey> {
720        if self
721            .current
722            .read()
723            .expect("KeyManager current lock poisoned")
724            .version
725            == version
726        {
727            return Some(
728                self.current
729                    .read()
730                    .expect("KeyManager current lock poisoned")
731                    .clone(),
732            );
733        }
734        self.previous
735            .read()
736            .expect("KeyManager previous lock poisoned")
737            .iter()
738            .find(|k| k.version == version)
739            .cloned()
740    }
741
742    /// Return the number of retained old keys.
743    pub fn previous_count(&self) -> usize {
744        self.previous
745            .read()
746            .expect("KeyManager previous lock poisoned")
747            .len()
748    }
749}
750
751// ============================================================================
752// 辅助函数
753// ============================================================================
754
755fn hex_encode(bytes: &[u8]) -> String {
756    bytes.iter().map(|b| format!("{:02x}", b)).collect()
757}
758
759fn hex_decode(hex: &str) -> Result<Vec<u8>, ()> {
760    if !hex.len().is_multiple_of(2) {
761        return Err(());
762    }
763    (0..hex.len())
764        .step_by(2)
765        .map(|i| u8::from_str_radix(&hex[i..i + 2], 16).map_err(|_| ()))
766        .collect()
767}
768
769fn random_bytes(len: usize) -> Vec<u8> {
770    let mut result = vec![0u8; len];
771    OsRng.fill_bytes(&mut result);
772    result
773}
774
775// ============================================================================
776// 错误类型
777// ============================================================================
778
779#[derive(Debug)]
780pub enum CryptoError {
781    EncryptionFailed(String),
782    DecryptionFailed(String),
783    InvalidKey(String),
784    InvalidNonce(String),
785    InvalidHash(String),
786    SigningFailed(String),
787}
788
789impl std::fmt::Display for CryptoError {
790    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
791        match self {
792            CryptoError::EncryptionFailed(msg) => write!(f, "Encryption failed: {}", msg),
793            CryptoError::DecryptionFailed(msg) => write!(f, "Decryption failed: {}", msg),
794            CryptoError::InvalidKey(msg) => write!(f, "Invalid key: {}", msg),
795            CryptoError::InvalidNonce(msg) => write!(f, "Invalid nonce: {}", msg),
796            CryptoError::InvalidHash(msg) => write!(f, "Invalid hash: {}", msg),
797            CryptoError::SigningFailed(msg) => write!(f, "Signing failed: {}", msg),
798        }
799    }
800}
801
802impl std::error::Error for CryptoError {}
803
804impl serde::Serialize for CryptoError {
805    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
806    where
807        S: serde::Serializer,
808    {
809        serializer.serialize_str(&self.to_string())
810    }
811}
812
813// ============================================================================
814// 测试
815// ============================================================================
816
817#[cfg(test)]
818mod tests {
819    use super::*;
820
821    // --- SHA-256 标准测试向量 (FIPS 180-2 / NIST) ---
822
823    #[test]
824    fn test_sha256_empty() {
825        assert_eq!(
826            sha256_hex(b""),
827            "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
828        );
829    }
830
831    #[test]
832    fn test_sha256_abc() {
833        assert_eq!(
834            sha256_hex(b"abc"),
835            "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
836        );
837    }
838
839    #[test]
840    fn test_sha256_hello() {
841        assert_eq!(
842            sha256_hex(b"hello"),
843            "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
844        );
845    }
846
847    #[test]
848    fn test_sha256_long_message() {
849        assert_eq!(
850            sha256_hex(b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
851            "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"
852        );
853    }
854
855    #[test]
856    fn test_sha256_deterministic() {
857        assert_eq!(sha256_hex(b"test"), sha256_hex(b"test"));
858        assert_ne!(sha256_hex(b"test"), sha256_hex(b"Test"));
859    }
860
861    // --- HMAC-SHA256 测试向量 (RFC 4231) ---
862
863    #[test]
864    fn test_hmac_sha256_rfc4231_case1() {
865        let key = vec![0x0bu8; 20];
866        let result = hmac_sha256_hex(&key, b"Hi There");
867        assert_eq!(
868            result,
869            "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"
870        );
871    }
872
873    #[test]
874    fn test_hmac_sha256_rfc4231_case2() {
875        let result = hmac_sha256_hex(b"Jefe", b"what do ya want for nothing?");
876        assert_eq!(
877            result,
878            "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"
879        );
880    }
881
882    #[test]
883    fn test_hmac_sha256_long_key() {
884        let key = vec![0xaau8; 130];
885        let result = hmac_sha256_hex(&key, b"test message");
886        assert_eq!(result.len(), 64);
887        let short_key = vec![0xaau8; 32];
888        let result_short = hmac_sha256_hex(&short_key, b"test message");
889        assert_ne!(result, result_short);
890    }
891
892    #[test]
893    fn test_hmac_sha256_different_messages() {
894        let key = b"secret";
895        assert_ne!(hmac_sha256_hex(key, b"msg1"), hmac_sha256_hex(key, b"msg2"));
896    }
897
898    // --- AesGcmCrypter 测试 ---
899
900    #[test]
901    fn test_aes_gcm_roundtrip() {
902        let key = [0x42u8; 32];
903        let crypter = AesGcmCrypter::new(&key);
904        let plaintext = b"Hello, World!";
905        let encrypted = crypter.encrypt(plaintext).unwrap();
906        let decrypted = crypter.decrypt(&encrypted).unwrap();
907        assert_eq!(decrypted, plaintext);
908    }
909
910    #[test]
911    fn test_aes_gcm_random_nonce_per_encryption() {
912        let key = [0x42u8; 32];
913        let crypter = AesGcmCrypter::new(&key);
914        let plaintext = b"same plaintext";
915        let encrypted1 = crypter.encrypt(plaintext).unwrap();
916        let encrypted2 = crypter.encrypt(plaintext).unwrap();
917        assert_ne!(encrypted1, encrypted2, "随机 nonce 应使密文不同");
918        assert_eq!(crypter.decrypt(&encrypted1).unwrap(), plaintext);
919        assert_eq!(crypter.decrypt(&encrypted2).unwrap(), plaintext);
920    }
921
922    #[test]
923    fn test_aes_gcm_from_key_str() {
924        let crypter = AesGcmCrypter::from_key_str("my-secret-key");
925        let plaintext = b"data to encrypt";
926        let encrypted = crypter.encrypt(plaintext).unwrap();
927        let decrypted = crypter.decrypt(&encrypted).unwrap();
928        assert_eq!(decrypted, plaintext);
929    }
930
931    #[test]
932    fn test_aes_gcm_short_ciphertext() {
933        let key = [0x42u8; 32];
934        let crypter = AesGcmCrypter::new(&key);
935        assert!(crypter.decrypt(&[0u8; 8]).is_err());
936    }
937
938    #[test]
939    fn test_aes_gcm_empty_plaintext() {
940        let key = [0x42u8; 32];
941        let crypter = AesGcmCrypter::new(&key);
942        let encrypted = crypter.encrypt(b"").unwrap();
943        // nonce(12) + tag(16) = 28
944        assert_eq!(encrypted.len(), 28);
945        let decrypted = crypter.decrypt(&encrypted).unwrap();
946        assert_eq!(decrypted, b"");
947    }
948
949    #[test]
950    fn test_aes_gcm_tampered_ciphertext() {
951        let key = [0x42u8; 32];
952        let crypter = AesGcmCrypter::new(&key);
953        let encrypted = crypter.encrypt(b"sensitive data").unwrap();
954        let mut tampered = encrypted.clone();
955        tampered[15] ^= 0x01;
956        assert!(crypter.decrypt(&tampered).is_err());
957    }
958
959    // --- Pbkdf2Hasher 测试 ---
960
961    #[test]
962    fn test_pbkdf2_hasher_hash_format() {
963        let hasher = Pbkdf2Hasher::new();
964        let hash = hasher.hash("password123").unwrap();
965        assert!(hash.starts_with('$'));
966        let parts: Vec<&str> = hash[1..].splitn(3, '$').collect();
967        assert_eq!(parts.len(), 3);
968        assert_eq!(parts[0].parse::<u32>().unwrap(), 100_000);
969        // salt 32 hex chars (16 bytes)
970        assert_eq!(parts[1].len(), 32);
971        // hash 64 hex chars (32 bytes)
972        assert_eq!(parts[2].len(), 64);
973    }
974
975    #[test]
976    fn test_pbkdf2_hasher_verify_correct() {
977        let hasher = Pbkdf2Hasher::new();
978        let hash = hasher.hash("password123").unwrap();
979        assert!(hasher.verify("password123", &hash).unwrap());
980    }
981
982    #[test]
983    fn test_pbkdf2_hasher_verify_wrong() {
984        let hasher = Pbkdf2Hasher::new();
985        let hash = hasher.hash("password123").unwrap();
986        assert!(!hasher.verify("wrongpassword", &hash).unwrap());
987    }
988
989    #[test]
990    fn test_pbkdf2_hasher_different_passwords_different_hashes() {
991        let hasher = Pbkdf2Hasher::new();
992        let h1 = hasher.hash("pass1").unwrap();
993        let h2 = hasher.hash("pass2").unwrap();
994        assert_ne!(h1, h2);
995    }
996
997    #[test]
998    fn test_pbkdf2_hasher_same_password_different_salts() {
999        let hasher = Pbkdf2Hasher::new();
1000        let h1 = hasher.hash("same").unwrap();
1001        let h2 = hasher.hash("same").unwrap();
1002        assert_ne!(h1, h2);
1003        assert!(hasher.verify("same", &h1).unwrap());
1004        assert!(hasher.verify("same", &h2).unwrap());
1005    }
1006
1007    #[test]
1008    fn test_pbkdf2_hasher_invalid_format() {
1009        let hasher = Pbkdf2Hasher::new();
1010        assert!(hasher.verify("password", "invalid-hash").is_err());
1011        assert!(hasher.verify("password", "$abc").is_err());
1012        assert!(hasher.verify("password", "$abc$def").is_err());
1013    }
1014
1015    #[test]
1016    fn test_pbkdf2_hasher_with_iterations() {
1017        // v4.8.0 修复 M-8:低于下限(100_000)的迭代配置被拒绝
1018        let low = Pbkdf2Hasher::with_iterations(1000);
1019        assert!(low.hash("secret").is_err());
1020
1021        let hasher = Pbkdf2Hasher::with_iterations(100_000);
1022        let hash = hasher.hash("secret").unwrap();
1023        let parts: Vec<&str> = hash[1..].splitn(3, '$').collect();
1024        assert_eq!(parts[0], "100000");
1025        assert!(hasher.verify("secret", &hash).unwrap());
1026    }
1027
1028    #[test]
1029    fn test_pbkdf2_hasher_empty_password() {
1030        let hasher = Pbkdf2Hasher::new();
1031        assert!(hasher.hash("").is_err());
1032    }
1033
1034    // --- HmacSigner 测试 ---
1035
1036    #[test]
1037    fn test_hmac_signer_sign_not_empty() {
1038        let signer = HmacSigner::new();
1039        let mut params = HashMap::new();
1040        params.insert("name".to_string(), "test".to_string());
1041        let signature = signer.sign(&params, "secret123");
1042        assert_eq!(signature.len(), 64);
1043    }
1044
1045    #[test]
1046    fn test_hmac_signer_verify_correct() {
1047        let signer = HmacSigner::new();
1048        let mut params = HashMap::new();
1049        params.insert("name".to_string(), "test".to_string());
1050        params.insert("age".to_string(), "25".to_string());
1051
1052        let signature = signer.sign(&params, "mysecret");
1053        assert!(signer.verify(&params, "mysecret", &signature));
1054    }
1055
1056    #[test]
1057    fn test_hmac_signer_verify_wrong_secret() {
1058        let signer = HmacSigner::new();
1059        let mut params = HashMap::new();
1060        params.insert("name".to_string(), "test".to_string());
1061        let signature = signer.sign(&params, "correctsecret");
1062        assert!(!signer.verify(&params, "wrongsecret", &signature));
1063    }
1064
1065    #[test]
1066    fn test_hmac_signer_verify_wrong_signature() {
1067        let signer = HmacSigner::new();
1068        let mut params = HashMap::new();
1069        params.insert("name".to_string(), "test".to_string());
1070        let valid_sig = signer.sign(&params, "secret");
1071        let tampered = if let Some(stripped) = valid_sig.strip_prefix('0') {
1072            format!("1{}", stripped)
1073        } else {
1074            format!("0{}", &valid_sig[1..])
1075        };
1076        assert!(!signer.verify(&params, "secret", &tampered));
1077    }
1078
1079    #[test]
1080    fn test_hmac_signer_different_params_different_signatures() {
1081        let signer = HmacSigner::new();
1082        let mut params1 = HashMap::new();
1083        params1.insert("a".to_string(), "1".to_string());
1084
1085        let mut params2 = HashMap::new();
1086        params2.insert("b".to_string(), "2".to_string());
1087
1088        let sig1 = signer.sign(&params1, "secret");
1089        let sig2 = signer.sign(&params2, "secret");
1090        assert_ne!(sig1, sig2);
1091    }
1092
1093    #[test]
1094    fn test_hmac_signer_param_order_independent() {
1095        let signer = HmacSigner::new();
1096        let mut params1 = HashMap::new();
1097        params1.insert("b".to_string(), "2".to_string());
1098        params1.insert("a".to_string(), "1".to_string());
1099
1100        let mut params2 = HashMap::new();
1101        params2.insert("a".to_string(), "1".to_string());
1102        params2.insert("b".to_string(), "2".to_string());
1103
1104        let sig1 = signer.sign(&params1, "secret");
1105        let sig2 = signer.sign(&params2, "secret");
1106        assert_eq!(sig1, sig2);
1107    }
1108
1109    #[test]
1110    fn test_hmac_signer_empty_params() {
1111        let signer = HmacSigner::new();
1112        let params = HashMap::new();
1113        let sig = signer.sign(&params, "secret");
1114        assert_eq!(sig.len(), 64);
1115        assert!(signer.verify(&params, "secret", &sig));
1116    }
1117
1118    // --- 辅助函数测试 ---
1119
1120    #[test]
1121    fn test_random_bytes_length() {
1122        assert_eq!(random_bytes(0).len(), 0);
1123        assert_eq!(random_bytes(16).len(), 16);
1124        assert_eq!(random_bytes(100).len(), 100);
1125    }
1126
1127    #[test]
1128    fn test_random_bytes_random() {
1129        let a = random_bytes(32);
1130        let b = random_bytes(32);
1131        assert_ne!(a, b, "随机字节序列应不同");
1132    }
1133
1134    #[test]
1135    fn test_constant_time_eq() {
1136        assert!(constant_time_eq(b"abc", b"abc"));
1137        assert!(!constant_time_eq(b"abc", b"abd"));
1138        assert!(!constant_time_eq(b"abc", b"ab"));
1139        assert!(!constant_time_eq(b"abc", b"abcd"));
1140        assert!(constant_time_eq(b"", b""));
1141    }
1142
1143    #[test]
1144    fn test_hex_encode_decode_roundtrip() {
1145        let original = vec![0x00, 0xff, 0xab, 0x42];
1146        let encoded = hex_encode(&original);
1147        let decoded = hex_decode(&encoded).unwrap();
1148        assert_eq!(decoded, original);
1149    }
1150
1151    #[test]
1152    fn test_hex_decode_invalid() {
1153        assert!(hex_decode("abc").is_err());
1154        assert!(hex_decode("xy").is_err());
1155    }
1156
1157    // ===== AES-GCM AAD 测试 =====
1158
1159    #[test]
1160    fn test_aes_gcm_aad_roundtrip() {
1161        let key = [0x42u8; 32];
1162        let crypter = AesGcmCrypter::new(&key);
1163        let plaintext = b"sensitive data";
1164        let aad = b"associated metadata";
1165        let encrypted = crypter.encrypt_with_aad(plaintext, aad).unwrap();
1166        let decrypted = crypter.decrypt_with_aad(&encrypted, aad).unwrap();
1167        assert_eq!(decrypted, plaintext);
1168    }
1169
1170    #[test]
1171    fn test_aes_gcm_aad_wrong_aad_fails() {
1172        let key = [0x42u8; 32];
1173        let crypter = AesGcmCrypter::new(&key);
1174        let plaintext = b"sensitive data";
1175        let aad = b"correct aad";
1176        let encrypted = crypter.encrypt_with_aad(plaintext, aad).unwrap();
1177        // 使用错误的 AAD 解密应失败
1178        let result = crypter.decrypt_with_aad(&encrypted, b"wrong aad");
1179        assert!(result.is_err());
1180    }
1181
1182    #[test]
1183    fn test_aes_gcm_aad_empty_aad_equivalent_to_no_aad() {
1184        let key = [0x42u8; 32];
1185        let crypter = AesGcmCrypter::new(&key);
1186        let plaintext = b"test data";
1187        // 空 AAD 等价于无 AAD
1188        let encrypted_no_aad = crypter.encrypt(plaintext).unwrap();
1189        let encrypted_empty_aad = crypter.encrypt_with_aad(plaintext, b"").unwrap();
1190        // 两者都应能解密
1191        assert_eq!(crypter.decrypt(&encrypted_no_aad).unwrap(), plaintext);
1192        assert_eq!(
1193            crypter.decrypt_with_aad(&encrypted_empty_aad, b"").unwrap(),
1194            plaintext
1195        );
1196    }
1197
1198    #[test]
1199    fn test_aes_gcm_aad_tampered_ciphertext_fails() {
1200        let key = [0x42u8; 32];
1201        let crypter = AesGcmCrypter::new(&key);
1202        let encrypted = crypter.encrypt_with_aad(b"data", b"aad").unwrap();
1203        let mut tampered = encrypted.clone();
1204        tampered[15] ^= 0x01;
1205        assert!(crypter.decrypt_with_aad(&tampered, b"aad").is_err());
1206    }
1207
1208    #[test]
1209    fn test_aes_gcm_aad_empty_plaintext() {
1210        let key = [0x42u8; 32];
1211        let crypter = AesGcmCrypter::new(&key);
1212        let encrypted = crypter.encrypt_with_aad(b"", b"aad").unwrap();
1213        // nonce(12) + tag(16) = 28
1214        assert_eq!(encrypted.len(), 28);
1215        let decrypted = crypter.decrypt_with_aad(&encrypted, b"aad").unwrap();
1216        assert_eq!(decrypted, b"");
1217    }
1218
1219    // ===== RSA-OAEP 测试 =====
1220
1221    #[test]
1222    fn test_rsa_oaep_roundtrip() {
1223        let crypter = RsaOaepCrypter::generate(2048).expect("RSA key generation");
1224        let plaintext = b"Hello, RSA-OAEP!";
1225        let encrypted = crypter.encrypt(plaintext).unwrap();
1226        let decrypted = crypter.decrypt(&encrypted).unwrap();
1227        assert_eq!(decrypted, plaintext);
1228    }
1229
1230    #[test]
1231    fn test_rsa_oaep_different_ciphertexts_same_plaintext() {
1232        let crypter = RsaOaepCrypter::generate(2048).unwrap();
1233        let plaintext = b"same message";
1234        let enc1 = crypter.encrypt(plaintext).unwrap();
1235        let enc2 = crypter.encrypt(plaintext).unwrap();
1236        // OAEP 使用随机填充,相同明文应产生不同密文
1237        assert_ne!(enc1, enc2);
1238        // 但两者都能正确解密
1239        assert_eq!(crypter.decrypt(&enc1).unwrap(), plaintext);
1240        assert_eq!(crypter.decrypt(&enc2).unwrap(), plaintext);
1241    }
1242
1243    #[test]
1244    fn test_rsa_oaep_empty_plaintext() {
1245        let crypter = RsaOaepCrypter::generate(2048).unwrap();
1246        let encrypted = crypter.encrypt(b"").unwrap();
1247        let decrypted = crypter.decrypt(&encrypted).unwrap();
1248        assert_eq!(decrypted, b"");
1249    }
1250
1251    #[test]
1252    fn test_rsa_oaep_tampered_ciphertext_fails() {
1253        let crypter = RsaOaepCrypter::generate(2048).unwrap();
1254        let encrypted = crypter.encrypt(b"secret").unwrap();
1255        let mut tampered = encrypted.clone();
1256        tampered[0] ^= 0x01;
1257        assert!(crypter.decrypt(&tampered).is_err());
1258    }
1259
1260    #[test]
1261    fn test_rsa_oaep_max_message_length() {
1262        // 2048-bit RSA-OAEP with SHA-256: max message = 2048/8 - 2*32 - 2 = 190 bytes
1263        let crypter = RsaOaepCrypter::generate(2048).unwrap();
1264        let plaintext = vec![0xABu8; 190];
1265        let encrypted = crypter.encrypt(&plaintext).unwrap();
1266        let decrypted = crypter.decrypt(&encrypted).unwrap();
1267        assert_eq!(decrypted, plaintext);
1268    }
1269
1270    #[test]
1271    fn test_rsa_oaep_oversized_message_fails() {
1272        let crypter = RsaOaepCrypter::generate(2048).unwrap();
1273        // 超过最大消息长度(190 字节 + 1)
1274        let plaintext = vec![0xABu8; 191];
1275        assert!(crypter.encrypt(&plaintext).is_err());
1276    }
1277
1278    #[test]
1279    fn test_rsa_oaep_from_keys() {
1280        let crypter1 = RsaOaepCrypter::generate(2048).unwrap();
1281        let crypter2 = RsaOaepCrypter::from_keys(
1282            crypter1.public_key().clone(),
1283            crypter1.private_key().clone(),
1284        );
1285        let plaintext = b"test from_keys";
1286        let encrypted = crypter2.encrypt(plaintext).unwrap();
1287        let decrypted = crypter2.decrypt(&encrypted).unwrap();
1288        assert_eq!(decrypted, plaintext);
1289    }
1290
1291    #[test]
1292    fn test_rsa_oaep_crypter_trait() {
1293        let crypter = RsaOaepCrypter::generate(2048).unwrap();
1294        let plaintext = b"trait test";
1295        let encrypted = Crypter::encrypt(&crypter, plaintext).unwrap();
1296        let decrypted = Crypter::decrypt(&crypter, &encrypted).unwrap();
1297        assert_eq!(decrypted, plaintext);
1298    }
1299
1300    // ===== HMAC 签名验证器测试 =====
1301
1302    #[test]
1303    fn test_hmac_signature_verifier_sign_verify() {
1304        let verifier = HmacSignatureVerifier::new(b"my-secret-key");
1305        let message = b"important message";
1306        let signature = verifier.sign(message);
1307        assert_eq!(signature.len(), 32);
1308        assert!(verifier.verify(message, &signature));
1309    }
1310
1311    #[test]
1312    fn test_hmac_signature_verifier_wrong_message() {
1313        let verifier = HmacSignatureVerifier::new(b"key");
1314        let signature = verifier.sign(b"message1");
1315        assert!(!verifier.verify(b"message2", &signature));
1316    }
1317
1318    #[test]
1319    fn test_hmac_signature_verifier_wrong_signature() {
1320        let verifier = HmacSignatureVerifier::new(b"key");
1321        let signature = verifier.sign(b"message");
1322        let mut tampered = signature.clone();
1323        tampered[0] ^= 0x01;
1324        assert!(!verifier.verify(b"message", &tampered));
1325    }
1326
1327    #[test]
1328    fn test_hmac_signature_verifier_from_key_str() {
1329        let verifier = HmacSignatureVerifier::from_key_str("string-key");
1330        let message = b"test";
1331        let sig = verifier.sign(message);
1332        assert!(verifier.verify(message, &sig));
1333    }
1334
1335    #[test]
1336    fn test_hmac_signature_verifier_different_keys_different_signatures() {
1337        let v1 = HmacSignatureVerifier::new(b"key1");
1338        let v2 = HmacSignatureVerifier::new(b"key2");
1339        let message = b"same message";
1340        let sig1 = v1.sign(message);
1341        let sig2 = v2.sign(message);
1342        assert_ne!(sig1, sig2);
1343    }
1344
1345    #[test]
1346    fn test_hmac_signature_verifier_empty_message() {
1347        let verifier = HmacSignatureVerifier::new(b"key");
1348        let sig = verifier.sign(b"");
1349        assert_eq!(sig.len(), 32);
1350        assert!(verifier.verify(b"", &sig));
1351    }
1352
1353    #[test]
1354    fn test_hmac_signature_verifier_wrong_length_signature() {
1355        let verifier = HmacSignatureVerifier::new(b"key");
1356        // 长度不对的签名应验证失败
1357        assert!(!verifier.verify(b"message", b"short"));
1358        assert!(!verifier.verify(b"message", &[]));
1359    }
1360
1361    // ===== 密钥轮换测试 =====
1362
1363    #[test]
1364    fn test_key_rotation_initial_key() {
1365        let mgr = KeyRotationManager::with_initial_key(b"key-v1".to_vec());
1366        assert_eq!(mgr.current_version(), 1);
1367        assert_eq!(mgr.version_count(), 1);
1368        assert_eq!(mgr.versions(), vec![1]);
1369    }
1370
1371    #[test]
1372    fn test_key_rotation_sign_verify_current() {
1373        let mgr = KeyRotationManager::with_initial_key(b"secret-key".to_vec());
1374        let message = b"test message";
1375        let (version, signature) = mgr.sign(message);
1376        assert_eq!(version, 1);
1377        assert!(mgr.verify(message, version, &signature));
1378    }
1379
1380    #[test]
1381    fn test_key_rotation_old_version_still_valid() {
1382        let mut mgr = KeyRotationManager::with_initial_key(b"key-v1".to_vec());
1383        let message = b"persistent message";
1384        let (v1, sig1) = mgr.sign(message);
1385        // 轮换到新密钥
1386        mgr.rotate_key(b"key-v2".to_vec());
1387        let (v2, sig2) = mgr.sign(message);
1388        assert_eq!(v1, 1);
1389        assert_eq!(v2, 2);
1390        // 旧版本签名仍应验证通过
1391        assert!(mgr.verify(message, v1, &sig1));
1392        // 新版本签名也应验证通过
1393        assert!(mgr.verify(message, v2, &sig2));
1394    }
1395
1396    #[test]
1397    fn test_key_rotation_max_versions_evicts_oldest() {
1398        let mut mgr = KeyRotationManager::new(2);
1399        mgr.rotate_key(b"key-v1".to_vec());
1400        mgr.rotate_key(b"key-v2".to_vec());
1401        assert_eq!(mgr.version_count(), 2);
1402        // 第三次轮换应淘汰 v1
1403        mgr.rotate_key(b"key-v3".to_vec());
1404        assert_eq!(mgr.version_count(), 2);
1405        assert_eq!(mgr.versions(), vec![2, 3]);
1406        assert!(!mgr.versions().contains(&1));
1407    }
1408
1409    #[test]
1410    fn test_key_rotation_old_version_evicted_fails_verify() {
1411        let mut mgr = KeyRotationManager::new(2);
1412        mgr.rotate_key(b"key-v1".to_vec());
1413        let message = b"test";
1414        let (v1, sig1) = mgr.sign(message);
1415        mgr.rotate_key(b"key-v2".to_vec());
1416        mgr.rotate_key(b"key-v3".to_vec());
1417        // v1 已被淘汰,验证应失败
1418        assert!(!mgr.verify(message, v1, &sig1));
1419    }
1420
1421    #[test]
1422    fn test_key_rotation_wrong_version_fails() {
1423        let mgr = KeyRotationManager::with_initial_key(b"key".to_vec());
1424        let message = b"test";
1425        let (_, signature) = mgr.sign(message);
1426        // 使用不存在的版本号验证应失败
1427        assert!(!mgr.verify(message, 999, &signature));
1428    }
1429
1430    #[test]
1431    fn test_key_rotation_multiple_rotations() {
1432        let mut mgr = KeyRotationManager::new(5);
1433        for i in 1..=4 {
1434            let key = format!("key-v{}", i);
1435            let version = mgr.rotate_key(key.as_bytes().to_vec());
1436            assert_eq!(version, i as u32);
1437        }
1438        assert_eq!(mgr.current_version(), 4);
1439        assert_eq!(mgr.version_count(), 4);
1440        assert_eq!(mgr.versions(), vec![1, 2, 3, 4]);
1441    }
1442
1443    #[test]
1444    fn test_key_rotation_empty_manager_sign_returns_zero() {
1445        let mgr = KeyRotationManager::new(3);
1446        let (version, sig) = mgr.sign(b"message");
1447        assert_eq!(version, 0);
1448        assert!(sig.is_empty());
1449    }
1450
1451    #[test]
1452    fn test_key_rotation_verify_with_wrong_signature() {
1453        let mgr = KeyRotationManager::with_initial_key(b"key".to_vec());
1454        let message = b"test";
1455        let (version, _) = mgr.sign(message);
1456        let wrong_sig = vec![0u8; 32];
1457        assert!(!mgr.verify(message, version, &wrong_sig));
1458    }
1459
1460    #[test]
1461    fn test_key_rotation_max_versions_min_one() {
1462        // max_versions = 0 应被提升为 1
1463        let mut mgr = KeyRotationManager::new(0);
1464        mgr.rotate_key(b"k1".to_vec());
1465        mgr.rotate_key(b"k2".to_vec());
1466        assert_eq!(mgr.version_count(), 1);
1467        assert_eq!(mgr.versions(), vec![2]);
1468    }
1469
1470    // ===== KeyManager(并发密钥轮换)测试 =====
1471
1472    #[test]
1473    fn test_key_manager_initial_key() {
1474        let mgr = KeyManager::new(b"initial-key".to_vec());
1475        let current = mgr.current_key();
1476        assert_eq!(current.version, 1);
1477        assert_eq!(current.key, b"initial-key");
1478        assert_eq!(mgr.previous_count(), 0);
1479    }
1480
1481    #[test]
1482    fn test_key_manager_rotate_increments_version() {
1483        let mgr = KeyManager::new(b"v1".to_vec());
1484        assert!(mgr.rotate(b"v2".to_vec()).is_ok());
1485        let current = mgr.current_key();
1486        assert_eq!(current.version, 2);
1487        assert_eq!(current.key, b"v2");
1488        assert_eq!(mgr.previous_count(), 1);
1489    }
1490
1491    #[test]
1492    fn test_key_manager_key_by_version_current() {
1493        let mgr = KeyManager::new(b"v1".to_vec());
1494        let found = mgr.key_by_version(1).expect("v1 should exist");
1495        assert_eq!(found.key, b"v1");
1496    }
1497
1498    #[test]
1499    fn test_key_manager_key_by_version_previous() {
1500        let mgr = KeyManager::new(b"v1".to_vec());
1501        mgr.rotate(b"v2".to_vec()).unwrap();
1502        // 旧版本仍可查找
1503        let old = mgr.key_by_version(1).expect("v1 should still be retained");
1504        assert_eq!(old.key, b"v1");
1505        // 新版本也可查找
1506        let new = mgr.key_by_version(2).expect("v2 should exist");
1507        assert_eq!(new.key, b"v2");
1508    }
1509
1510    #[test]
1511    fn test_key_manager_key_by_version_not_found() {
1512        let mgr = KeyManager::new(b"v1".to_vec());
1513        assert!(mgr.key_by_version(999).is_none());
1514    }
1515
1516    #[test]
1517    fn test_key_manager_retains_at_most_three_previous() {
1518        let mgr = KeyManager::new(b"v1".to_vec());
1519        mgr.rotate(b"v2".to_vec()).unwrap();
1520        mgr.rotate(b"v3".to_vec()).unwrap();
1521        mgr.rotate(b"v4".to_vec()).unwrap();
1522        // 3 次轮换后 previous 应有 3 个,再轮换一次应淘汰最早的
1523        assert_eq!(mgr.previous_count(), 3);
1524        mgr.rotate(b"v5".to_vec()).unwrap();
1525        assert_eq!(mgr.previous_count(), 3);
1526        // v1 应已被淘汰
1527        assert!(mgr.key_by_version(1).is_none());
1528        // v2 仍应存在
1529        assert!(mgr.key_by_version(2).is_some());
1530        // 当前版本为 5
1531        assert_eq!(mgr.current_key().version, 5);
1532    }
1533
1534    #[test]
1535    fn test_key_manager_needs_rotation_false_initially() {
1536        let mgr = KeyManager::new(b"k".to_vec());
1537        // 刚创建不应需要轮换
1538        assert!(!mgr.needs_rotation());
1539    }
1540
1541    #[test]
1542    fn test_key_manager_needs_rotation_true_after_interval() {
1543        let mgr = KeyManager::new(b"k".to_vec()).with_rotation_interval(Duration::from_millis(0));
1544        // 间隔为 0,应立即需要轮换
1545        std::thread::sleep(Duration::from_millis(1));
1546        assert!(mgr.needs_rotation());
1547    }
1548
1549    #[test]
1550    fn test_key_manager_with_rotation_interval() {
1551        let mgr = KeyManager::new(b"k".to_vec()).with_rotation_interval(Duration::from_secs(60));
1552        assert!(!mgr.needs_rotation());
1553    }
1554
1555    #[test]
1556    fn test_key_manager_rotate_resets_last_rotation() {
1557        let mgr = KeyManager::new(b"k".to_vec()).with_rotation_interval(Duration::from_millis(1));
1558        std::thread::sleep(Duration::from_millis(5));
1559        assert!(mgr.needs_rotation());
1560        mgr.rotate(b"k2".to_vec()).unwrap();
1561        // 轮换后应不再立即需要轮换
1562        assert!(!mgr.needs_rotation());
1563    }
1564
1565    #[test]
1566    fn test_key_manager_concurrent_access() {
1567        use std::sync::Arc;
1568        use std::thread;
1569        let mgr = Arc::new(KeyManager::new(b"base".to_vec()));
1570        let mut handles = vec![];
1571        // 并发读
1572        for _ in 0..4 {
1573            let m = mgr.clone();
1574            handles.push(thread::spawn(move || {
1575                let _ = m.current_key();
1576                let _ = m.previous_count();
1577            }));
1578        }
1579        for h in handles {
1580            h.join().expect("thread panicked");
1581        }
1582        // 并发读不应改变状态
1583        assert_eq!(mgr.current_key().version, 1);
1584    }
1585}