C#中解密8字节数组遇Rijndael密钥尺寸无效错误的排查
问题根源与解决方案
核心问题
你用了AES算法的实现类(RijndaelManaged),但AES不支持8字节(64位)密钥——AES的合法密钥长度只有128/192/256位,对应16/24/32字节。而MIFARE DESFire使用8字节密钥时,采用的是DES算法(或3DES),不是AES,这就是报错的根本原因。
解决步骤
- 替换算法实现:把
RijndaelManaged换成DES专用的加密类,比如DESCryptoServiceProvider。 - 匹配DES参数:DES的密钥和IV长度刚好是8字节,完全符合你的需求。
- 对齐DESFire的加密规则:必须和伪代码中的加密模式(ECB/CBC)、填充方式保持一致,否则解密结果会出错。
修改后的示例代码
public class DesGenericEncryptionService { private readonly byte[] m_Key; private readonly byte[] m_IV; public DesGenericEncryptionService(byte[] key, byte[] iv) { m_Key = key ?? throw new ArgumentNullException(nameof(key)); m_IV = iv ?? throw new ArgumentNullException(nameof(iv)); if (m_Key.Length != 8) throw new ArgumentException("DES密钥必须是8字节", nameof(key)); if (m_IV.Length != 8) throw new ArgumentException("DES IV必须是8字节", nameof(iv)); } public byte[] Decrypt(byte[] data) { if (data == null || data.Length == 0) throw new ArgumentNullException(nameof(data)); // DES要求数据长度是8字节的倍数,和你的8字节解密需求匹配 if (data.Length % 8 != 0) throw new ArgumentException("解密数据长度必须是8字节的倍数", nameof(data)); using (var des = new DESCryptoServiceProvider()) { des.Key = m_Key; des.IV = m_IV; // 根据DESFire伪代码调整模式,比如ECB是常见选项 des.Mode = CipherMode.ECB; // 同样根据伪代码调整填充,比如NoPadding或ISO7816-4填充 des.Padding = PaddingMode.None; using (var decryptor = des.CreateDecryptor()) using (var ms = new MemoryStream(data)) using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) { var result = new byte[data.Length]; cs.Read(result, 0, result.Length); return result; } } } }
关键注意点
- 一定要严格匹配伪代码中的
Mode和Padding:比如DESFire常用的是CipherMode.ECB+PaddingMode.None,或者CipherMode.CBC配合对应IV;若伪代码用了ISO7816-4填充,要改成PaddingMode.None后手动处理填充字节。 - 如果你的伪代码是3DES(Triple DES),则替换成
TripleDESCryptoServiceProvider,3DES支持8字节密钥(会重复使用密钥形成16字节的3DES密钥)。
内容的提问来源于stack exchange,提问作者the1.9gpaProgrammer
相关产品推荐
相关产品推荐

