C# 为什么可以';我们是否只使用密码短语的散列作为对称加密算法的加密密钥(和IV)?

C# 为什么可以';我们是否只使用密码短语的散列作为对称加密算法的加密密钥(和IV)?,c#,.net,security,encryption,cryptography,C#,.net,Security,Encryption,Cryptography,受此启发,现在我有了一个非常有趣的想法:您是否真的需要使用Rfc2898DeriveBytes或类似的类来“安全地派生”来自密码短语字符串的加密密钥和初始化向量,或者该字符串的简单散列是否与密钥/IV同样有效,使用对称算法(如AES、DES等)加密数据时 我看到了大量AES加密代码片段,其中Rfc2898DeriveBytes类用于从密码字符串派生加密密钥和初始化向量(IV)。我们假设应该使用一个随机的salt和大量的迭代来为加密导出足够安全的key/IV。虽然使用此方法从密码字符串派生字节在某

受此启发,现在我有了一个非常有趣的想法:您是否真的需要使用
Rfc2898DeriveBytes
或类似的类来“安全地派生”来自密码短语字符串的加密密钥和初始化向量,或者该字符串的简单散列是否与密钥/IV同样有效,使用对称算法(如AES、DES等)加密数据时

我看到了大量AES加密代码片段,其中
Rfc2898DeriveBytes
类用于从密码字符串派生加密密钥和初始化向量(IV)。我们假设应该使用一个随机的salt和大量的迭代来为加密导出足够安全的key/IV。虽然使用此方法从密码字符串派生字节在某些情况下非常有用,但我认为在使用对称算法加密数据时,这不适用!原因如下:当有可能构建预先计算的rainbow表时,使用salt是有意义的,当攻击者获得哈希时,他会查找原始密码。但是对于对称数据加密,我认为这不是必需的,因为密码字符串或加密密钥的散列永远不会存储在任何地方。因此,如果我们只获取密码的SHA1散列,并将其用作加密密钥/IV,这不是同样安全吗

使用
Rfc2898DeriveBytes
类从密码字符串生成key/IV(这是一个非常高性能的操作)的目的是什么,而我们只能使用该密码的SHA1(或任何其他)散列?散列将导致密钥中的随机位分布(与直接使用字符串字节相反)。而且攻击者必须强制执行整个密钥范围(例如,如果密钥长度为256bit,他必须尝试2^256个组合)


因此,要么我以一种危险的方式错了,要么所有使用
Rfc2898DeriveBytes
方法生成加密密钥和IV的AES加密示例(包括这里的许多上选答案)等都是错误的。

Rfc2898DeriveBytes的关键是要慢一些。

通过重复散列1000次或更多次,您可以强制蛮力尝试猜测密码的速度要慢几个数量级。

如果您使用密码的散列作为加密密钥,则每次加密的密钥都会不同,这使得攻击者更容易攻击至少一些加密值(通过散列)“password123”、“chocolate”等)。保护对称加密的最佳方法是管理一个长且单一的密钥,这样任何人都无法嗅到它。
至于你的第一个问题,关于使用Rfc2898DeriveBytes,这一点是为了确保你从密码中获得的密钥是以一种难以复制或暴力的方式完成的。这会在过程中增加熵。如果你获取一个密码,然后执行一个简单的哈希,用于加密的密码将是脆弱的(限制字符集和长度)和可预测

攻击者必须对整个密钥范围进行暴力破解(例如,如果 密钥长度为256(但他必须尝试2^256个组合)


这就是你出错的地方。如果弱密码有8个字符,每个ASCII字符大约有5位,那么大约有(2^5)^8个弱密码,大约为2^40。由于您没有使用salt,因此只有2^40个可能的密钥。通过迭代8个字符的可能组合并对每个字符进行哈希运算,可以轻松生成这些密钥。这比使用2^256更容易。是的,但对称算法不需要这样做完全正确!攻击者会强制执行密钥本身,而不是密码字符串!因此我看不出有任何理由减慢从密码派生密钥的速度,因为攻击者会试图强制执行密钥本身,而不是它派生的密码。不是这样吗?@TX\ux:密码的大小远小于对称密钥的大小。它使暴力破解密码更有意义。@TX\n如果您添加了足够多的重复次数,使得重复破解密码需要0.1秒,那么暴力破解攻击者每秒最多可以尝试10个可能的密码。这将大大增加攻击者处理整个可能密码列表的时间。您不会超过她,但你会让她慢很多。Salting意味着她必须对每种不同的salt重复整个密码搜索。RFC2898有一个很好的理由。看你读过RFC 2898吗?这是一个很好的开始理解为什么选择它以这种方式实现密钥派生的地方。可以问你自己这些问题ons。不太好的是将您的想法逐字发布到stackoverflow。这显然是离题的。此外,PBKDF2是基于密码的加密的一部分。现在,如果这没有意义,您不认为现在有人会注意到吗?您真的读过RFC吗?Rfc2898DeriveBytes类清楚地指出了这一点?