我的任务是编写一个计算密码哈希的新方法来替换我们认为还不够安全的旧方法。很久以前,我读过Security Driven .NET一书,其中我了解到重要的部分是使用具有可配置转数的算法(而不是简单的哈希),而在.NET中推荐的是调用PBKDF2
进行密码处理。我还读到,作为ASP.NET如何处理密码的改进,如果存储在数据库中的结果哈希通过使用PBKDF2创建主数据加密地绑定到用户(名称或ID),那将是很好的键,然后使用用户名(或id)使用HKDF创建派生密钥。但同样,这是我从一本我目前无法访问的书中读到的肤浅的知识,所以如果我的记忆是正确的,我就无法重新检查。
另外,我之前没有使用过.NET DerivedBytes API,所以我可能做错了。所以我的问题是:我在下面的代码中做得对吗?我正确使用API吗?这种实施“足够安全”吗?或者我做错了哪些事情完全消除了所有安全措施?
protected override byte[] ComputeHash(string user, string salt, string password)
{
var userBytes = user.ToBytes();
using (var pbkdf2 = new PBKDF2(MacFactories.HMACSHA512, password.ToBytes(), salt.ToBytes()))
{
var masterKey = pbkdf2.GetBytes(128);
using (var hkdf = new HKDF(MacFactories.HMACSHA512, masterKey, userBytes, userBytes))
{
return hkdf.GetBytes(64);
}
}
}
答案 0 :(得分:4)
你有正确的想法/方法 - 这是一个稍微好一点的实现:
byte[] ComputeHash(string user, string salt, string password)
{
using (var pbkdf2 = new PBKDF2(HMACFactories.HMACSHA512, password, salt.ToBytes()))
using (var hkdf = new HKDF(HMACFactories.HMACSHA512, pbkdf2.GetBytes(64), user.ToBytes()))
return hkdf.GetBytes(64);
}
你不应该问pbkdf2
字节多于底层PRF的字节长度(在你的情况下,SHA512产生64字节)。
您可以将hkdf
上下文保留为null
,因为您似乎不需要它。
对于可能想知道上述代码使用的库的其他人 - Inferno crypto。