[英]Storing PBKDF2 Iterations
所以我正在使用.NET中的Rcfc2898DeriveBytes类将密码散列到数据库
散列并存储最终的散列和盐都可以正常工作。
但是,在计算散列密码时存储类运行的迭代次数时遇到了问题。
谷歌搜索之后,我只看到应该将其存储在密码哈希值之前,但是我不确定如何以这种方式进行处理,以防万一我以后要更改数字(无需存储密码)迭代,更改将破坏旧密码)。
我看到bcrypt将为您完成所有这些工作,但是我没有为项目添加库的奢望。
存储此数字的最佳方法是什么,我将如何去做,以便它可检索并且在存储时不仅会丢失在哈希中(一旦取回,如何将其与哈希分开)?
感谢您提前提供任何建议和信息!
原则上,您根本不必存储迭代量。 就像您不必保持哈希类型一致就可以存储它。
我会提出一些稍有不同的建议:将一个包含版本号(从零开始)的单个字节(前缀)存储在salt&hash之前。 该版本号与迭代次数,哈希方法,字符编码方法以及PBKDF2相关联。 如果要升级到更好的协议,只需将01
存储为初始字节,然后将其与新参数链接。 这样,您可以区分旧样式密码和新样式。
通常,只有在用户输入密码时才能进行升级,因为哈希是不可逆的,因此升级迭代次数不容易。
我在下面的网址中找到了所需的内容。
https://cmatskas.com/-net-password-hashing-using-pbkdf2/
相关代码在这里:
public class PasswordHash
{
public const int SALT_BYTE_SIZE = 24;
public const int HASH_BYTE_SIZE = 20;
public const int PBKDF2_ITERATIONS = 1000;
public const int ITERATION_INDEX = 0;
public const int SALT_INDEX = 1;
public const int PBKDF2_INDEX = 2;
public static string HashPassword(string password)
{
var cryptoProvider = new RNGCryptoServiceProvider();
byte[] salt = new byte[SALT_BYTE_SIZE];
cryptoProvider.GetBytes(salt);
var hash = PBKDF2(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);
return PBKDF2_ITERATIONS + ":" +
Convert.ToBase64String(salt) + ":" +
Convert.ToBase64String(hash);
}
public static bool ValidatePassword(string password, string correctHash)
{
char[] delimiter = { ':' };
var split = correctHash.Split(delimiter);
var iterations = Int32.Parse(split[ITERATION_INDEX]);
var salt = Convert.FromBase64String(split[SALT_INDEX]);
var hash = Convert.FromBase64String(split[PBKDF2_INDEX]);
var testHash = PBKDF2(password, salt, iterations, hash.Length);
return SlowEquals(hash, testHash);
}
}
我采用了HashPassword方法将值保存到数据库中,以备后用。 我使用ValidatePassword将其撤回,以便我再次使用。 它的工作原理很吸引人,它使我能够确定salt和hash的字节大小,并根据所需的强度来确定迭代次数。 这些值仅存储在Web / App配置文件中。
谢谢大家的回答!
在这里看看bcrypt如何存储散列: 在数据库中存储Bcrypt散列密码时应使用哪种列类型/长度?
因此,如果您仅打算更改迭代,则可以进行以下简单操作:
$<number of iterations>$<hash>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.