c# - 为什么任何长度的 key 都适用于 RijndaelManaged?

标签 c# .net cryptography rijndaelmanaged

关于方法...

RijndaelManaged.CreateDecryptor Method (Byte[], Byte[])

Here它说的是第一个参数...

The secret key to be used for the symmetric algorithm. The key size must be 128, 192, or 256 bits.

但我可以将 key 设置为任意长度的字符串...

var key = Encoding.UTF8.GetBytes("whetever...");

为什么不对字节数组的长度更加挑剔呢?它如何确定使用三个 key 长度中的哪一个?

最佳答案

并非任何 key 大小都有效。只应允许一组特定的 key 大小。

RijndaelManaged 的​​ LegalKeySizes 大小属性实际上报告以下值:

MinSize = 128
MaxSize = 256
SkipSize = 64

这应该表明仅支持 AES key 大小:128、192,当然还有 256。这基本上意味着 RijndaelManaged 没有完全实现 Rijndael,它也允许 160 和 224 位作为 key 尺寸。实际上,我认为它也不允许 160 和 224 位的 block 大小。

现在你的问题给我带来了一些问号,所以我决定看看哪些 key 大小实际上被接受而不引发异常,我得到了以下令人惊讶的结果:

8, 9, 10, 11, 12, 13, 14, 15, 16, 24, 32

或者,以位而不是字节为单位:

64, 72, 80, 88, 96, 104, 112, 120, 128, 192, 256

因此,RijndaelManaged 似乎接受比指定更多的 key 大小,并且这些额外的 key 大小低于类和 Rijndael 算法指定的最小长度。

现在让我们使用这些无效 key 大小来加密某些内容:

064 : 1903b797b48ce006e618cb605d356981cc9b231195420010916e449037d3ac5b
072 : 1903b797b48ce006e618cb605d356981cc9b231195420010916e449037d3ac5b
080 : 1903b797b48ce006e618cb605d356981cc9b231195420010916e449037d3ac5b
088 : 1903b797b48ce006e618cb605d356981cc9b231195420010916e449037d3ac5b
096 : 4002ae70943dafdec10d4fbe2f97dc95b0a61e7412277197623b6d3d3e0da31c
104 : 4002ae70943dafdec10d4fbe2f97dc95b0a61e7412277197623b6d3d3e0da31c
112 : 4002ae70943dafdec10d4fbe2f97dc95b0a61e7412277197623b6d3d3e0da31c
120 : 4002ae70943dafdec10d4fbe2f97dc95b0a61e7412277197623b6d3d3e0da31c
128 : 66e94bd4ef8a2c3b884cfa59ca342b2e9434dec2d00fdac765f00c0c11628cd1
192 : aae06992acbf52a3e8f4a96ec9300bd71045be567103016ac50b21b86fc5457e
256 : dc95c078a2408989ad48a21492842087f3c003ddc4a7b8a94baedffc3d214c38

注意:对于那些感兴趣的人: key 由全零组成的 CBC、明文和 IV 也只是设置为零的 16 个字节。测试在 Windows 10 上进行:

OS: Microsoft Windows NT 10.0.10240.0, CLR : 4.0.30319.42000

因此,对于 key 大小 64、72、80、88、96、104、112、120,您只会得到一些无效的、未指定的结果。查看代码,它基本上仅使用 8 个字节作为 key ,并将其他字节设置为 key 大小 8..11 为零, key 大小 12..15 为 12 字节。在这种情况下, block 大小将为 128 位,否则 block 大小将与 key 大小相同。因此,在将 key 用于 72、80、88、104、112 和 120 位的 key 之前,该实现实际上会从 key 末尾删除一到三个字节。

所以基本上这似乎是实现中的一个错误。基本上,您不应在 LegalKeySizes 返回的值之外使用 RijndaelManaged

<小时/>

如前所述,您应该使用 Rfc2898DeriveBytes将密码转换为具有有效 key 大小的 key 。

关于c# - 为什么任何长度的 key 都适用于 RijndaelManaged?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34343500/

相关文章:

.net - 在 ASP.NET MVC 的母版页中使用脚本

python - 如何在Python中使用x和y坐标验证ES384 JWT签名

emacs - 用于 Emacs Lisp 的 Ironclad 加密库?

c# - 禁用延迟加载仍然加载相关实体。为什么?

javascript - C# bool 函数正在从服务器返回一个对象到客户端

c# - PDB 文件在第二次编译时变大,然后保持相同大小

linux - 可以提高此用户名/密码生成器脚本的安全性吗?

c# - 我可以为 IEnumerable<T> 使用与 <T> 不同的扩展方法吗?

c# - 插入具有单行的数据表时,SqlBulkCopy 挂起而没有任何异常或超时

c# - 多次读取 IDataReader 时出错