如何根据密钥长度优雅初始化AES解码器(Rust aes crate)
解决Rust aes crate中根据密钥长度选择解码器的重复代码问题
针对你遇到的重复if-else代码问题,可以通过自定义统一Trait或封装枚举类型两种方式来优化,避免重复逻辑:
方法一:自定义统一Trait + 动态分派
先定义一个包含解密方法的Trait,为三个AES解码器分别实现该Trait,之后就能用 trait 对象统一处理:
use aes::{Aes128Dec, Aes192Dec, Aes256Dec}; use generic_array::GenericArray; use pkcs7::Pkcs7; use cipher::BlockDecryptMut; // 定义统一的解密Trait trait AesPaddedDecrypt { fn decrypt_pkcs7_b2b_mut(&mut self, data: &[u8], out: &mut [u8]) -> Result<(), cipher::Error>; } // 为Aes128Dec实现Trait impl AesPaddedDecrypt for Aes128Dec { fn decrypt_pkcs7_b2b_mut(&mut self, data: &[u8], out: &mut [u8]) -> Result<(), cipher::Error> { self.decrypt_padded_b2b_mut::<Pkcs7>(data, out) } } // 为Aes192Dec实现Trait impl AesPaddedDecrypt for Aes192Dec { fn decrypt_pkcs7_b2b_mut(&mut self, data: &[u8], out: &mut [u8]) -> Result<(), cipher::Error> { self.decrypt_padded_b2b_mut::<Pkcs7>(data, out) } } // 为Aes256Dec实现Trait impl AesPaddedDecrypt for Aes256Dec { fn decrypt_pkcs7_b2b_mut(&mut self, data: &[u8], out: &mut [u8]) -> Result<(), cipher::Error> { self.decrypt_padded_b2b_mut::<Pkcs7>(data, out) } }
使用时通过Box<dyn AesPaddedDecrypt>统一类型:
let mut dec_cipher: Box<dyn AesPaddedDecrypt> = match key_len { 0..=16 => Box::new(Aes128Dec::new(GenericArray::from_slice(key_bytes))), 17..=24 => Box::new(Aes192Dec::new(GenericArray::from_slice(key_bytes))), _ => Box::new(Aes256Dec::new(GenericArray::from_slice(key_bytes))), }; dec_cipher.decrypt_pkcs7_b2b_mut(data_bytes, &mut encoded)?;
方法二:封装枚举类型(静态分派,性能更优)
如果不想用动态分派,可以自定义枚举包裹三个解码器,在枚举中实现统一的解密方法,这种方式是静态分派,没有运行时开销:
use aes::{Aes128Dec, Aes192Dec, Aes256Dec}; use generic_array::GenericArray; use pkcs7::Pkcs7; use cipher::BlockDecryptMut; enum AesDecryptor { Aes128(Aes128Dec), Aes192(Aes192Dec), Aes256(Aes256Dec), } impl AesDecryptor { // 根据密钥长度创建对应解码器 fn from_key(key_bytes: &[u8]) -> Self { match key_bytes.len() { 0..=16 => AesDecryptor::Aes128(Aes128Dec::new(GenericArray::from_slice(key_bytes))), 17..=24 => AesDecryptor::Aes192(Aes192Dec::new(GenericArray::from_slice(key_bytes))), _ => AesDecryptor::Aes256(Aes256Dec::new(GenericArray::from_slice(key_bytes))), } } // 统一的PKCS7解密方法 fn decrypt_pkcs7_b2b_mut(&mut self, data: &[u8], out: &mut [u8]) -> Result<(), cipher::Error> { match self { AesDecryptor::Aes128(cipher) => cipher.decrypt_padded_b2b_mut::<Pkcs7>(data, out), AesDecryptor::Aes192(cipher) => cipher.decrypt_padded_b2b_mut::<Pkcs7>(data, out), AesDecryptor::Aes256(cipher) => cipher.decrypt_padded_b2b_mut::<Pkcs7>(data, out), } } }
使用时直接调用枚举方法:
let mut dec_cipher = AesDecryptor::from_key(key_bytes); dec_cipher.decrypt_pkcs7_b2b_mut(data_bytes, &mut encoded)?;
两种方案对比
- 动态分派(Trait对象):代码更简洁,适合需要扩展更多解码器的场景,但有轻微的运行时开销。
- 枚举封装:静态分派性能更好,没有额外开销,适合固定几种解码器的场景。
内容的提问来源于stack exchange,提问作者dpr
相关产品推荐
相关产品推荐

