我的代码真的需要8年左右才能破译

Ani*_*dha 4 .net c# security cryptography

在简单的书中阅读C#的Hashing主题时,我发现了以下引用!

您可以通过"拉伸"密码哈希来反复重复以提供更多计算密集型字节序列,从而提供针对字典攻击的额外保护.如果你重复100次,那么可能需要1个月的字典攻击需要8年.

所以我这样实现了!

byte[] data = Encoding.UTF8.GetBytes("Password is 12345679");
byte[] hash = SHA512.Create().ComputeHash(data);
int temp=0;
while (temp < 100)
{
    hash = SHA512.Create().ComputeHash(hash);
    temp++;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码是对的吗?字典攻击真的需要8年左右才能破译?

Rob*_*ier 6

在缺少快捷方式的情况下(正如@ Random832所指出的那样),人们应该期望它需要花费100倍的时间来进行暴力测试.如果攻击者正在查找寻找匹配的哈希的每个字符序列,那么使该哈希需要更长时间的任何事情都会降低他的速度(或者等效地使用更多的计算能力).

继续从Random832窃取,这是一个"穷人的伸展".它是足够和有用的,但是如果你有可用的PBKDF2功能,那是首选,因为密码学家可以很好地分析PBKDF2.在最严格的意义上,上面的代码是"基于密码的密钥派生函数"(PBKDF),但PBKDF2是特定的.编辑:我不是一个C#开发人员,但看起来.NET包含一个PBKDF2函数Rfc2898DeriveBytes.

请注意上面文本中的关键短语:"否则可能需要1个月." 作者假设它需要一个月才能完成第一次,而8年大约需要100个月.如果第一次执行字典攻击需要1分钟,你应该预计在第二次执行时需要大约1.5小时.这里没有神奇的"8年".它只是第一个数字的100倍,无论第一个数字是什么.

编辑:关于拉伸还有一点需要注意.在伸展之前你应该总是加盐.Salting意味着您将一系列随机字节添加到密码的开头.然后,您将该哈希值与哈希结果一起编码(盐不是秘密).因此,不是散列"密码是12345679",而是哈希"deadbeefPassword是12345679",然后你会发送"deadbeef"以及最终结果.这样做的原因是因为人们总是选择相同的密码.因此,如果攻击者计算出散列"Passw0rd!"的结果 然后他可以根据你的哈希检查结果.便宜得多.同样地,如果他同时拥有Alice和Bob的哈希,他可以判断它们是相同还是不同.但是使用随机盐,你不能这样做,因为几乎可以肯定Alice和Bob将使用不同的盐进行数据散列.