PasswordDeriveBytes按8+24字节顺序调用GetBytes触发ArgumentException
PasswordDeriveBytes 多次调用GetBytes顺序不同触发ArgumentException的原因
这是PasswordDeriveBytes这个已弃用类的实现Bug,根源在于它的默认算法和非标准扩展逻辑存在缺陷:
PasswordDeriveBytes默认使用PBKDF1算法,而PBKDF1的规范要求派生的总密钥长度不能超过底层哈希函数的输出长度(比如默认的SHA1是20字节)。但.NET对这个类做了非标准扩展,允许通过多次调用GetBytes生成超过哈希长度的字节,实现方式是每次调用时递增迭代计数器来生成新的哈希块。- 这个扩展的实现逻辑有漏洞:
- 先调用
GetBytes(24)时,它会一次性生成24字节(违反PBKDF1规范)并缓存,后续GetBytes(8)直接读取缓存剩余部分,不会报错。 - 先调用
GetBytes(8)后,内部偏移量被设为8,此时再调用GetBytes(24),需要从偏移8的位置生成24字节,内部数组计算出现越界,触发ArgumentException。
- 先调用
- 32/16字节组合两种顺序都正常是偶然情况,刚好避开了数组越界的触发条件,但这并不代表实现正确。
问题复现代码
var deriver1 = new PasswordDeriveBytes("mykey-123456789", []); var key1 = deriver1.GetBytes(24); var iv1 = deriver1.GetBytes(8); var deriver2 = new PasswordDeriveBytes("mykey-123456789", []); var iv2 = deriver2.GetBytes(8); var key2 = deriver2.GetBytes(24); // BOOM: ArgumentException: Offset and length were out of bounds...
内容的提问来源于stack exchange,提问作者user2537984
相关产品推荐
相关产品推荐

