- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试通过散列和加盐将密码保存在数据库中来学习密码学,所以我决定制作一个登录系统来尝试实现该系统。
我的数据库包括
我正在使用 PBKDF2,但这似乎不是一种散列/加盐方法,如果不是,那又是什么呢?
如果是这样,我这样做对吗?
我的 key
private const int SALT_SIZE = 64;
private const int KEY_SIZE = 64;
向数据库中插入数据
public static void RegisterMe(string _username, string _password, string _email)
{
using (var cn = new SqlConnection(User.strcon))
{
string _sqlins = @"
INSERT INTO
[User]
([Username],[Salt],[Password],[RegDate], [Email])
VALUES
(@Username, @Salt, @Password, CURRENT_TIMESTAMP, @Email)";
var cmd = new SqlCommand(_sqlins, cn);
cn.Open();
using (var deriveBytes = new Rfc2898DeriveBytes(_password, SALT_SIZE))
{
byte[] salt = deriveBytes.Salt;
byte[] key = deriveBytes.GetBytes(KEY_SIZE);
// save salt and key to database
cmd.Parameters.AddWithValue("@Username", _username);
cmd.Parameters.AddWithValue("@Password", key);
cmd.Parameters.AddWithValue("@Salt", salt);
cmd.Parameters.AddWithValue("@Email", _email);
}
cmd.ExecuteNonQuery();
}
}
检查用户是否有效
public bool IsValid(string _email, string _password)
{
using (var cn = new SqlConnection(strcon))
{
byte[] salt = { }, key = { };
string _sql = @"
SELECT
SALT,
[Password],
UserID
FROM
[User]
WHERE [Email] = @email";
SqlCommand cmd = new SqlCommand(_sql, cn);
cmd.Parameters.AddWithValue("@email", _email);
cn.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
salt = reader.GetSqlBytes(0).Value;
key = reader.GetSqlBytes(1).Value;
reader.Dispose();
cmd.Dispose();
using (var deriveBytes = new Rfc2898DeriveBytes(_password, salt))
{
byte[] newKey = deriveBytes.GetBytes(KEY_SIZE); // derive a 20-byte key
return newKey.SequenceEqual(key);
}
}
else
{
reader.Dispose();
cmd.Dispose();
return false;
}
}
}
我的系统工作正常,它将数据以字节形式设置到数据库中,如果用户输入正确的密码,它会返回 true。但这是正确的方法吗?这甚至是散列/加盐吗?
最佳答案
你基本上是在朝着正确的方向前进,但我会指出一些需要考虑的事情:
PBKDF2 方法的默认迭代次数可能不够,您可能不想保留默认值。我建议指定至少 10K 的迭代次数。
另一方面,此实现以字节为单位计算 key 大小和盐大小。 64 字节有点太多了。将两者都保持为 16 个字节应该足够了。不建议超过 20 个字节,因为这是底层哈希函数/HMAC 的最大大小。继续下去只会给攻击者带来优势(根据许多人的说法,这是 PBKDF2 中的设计错误)。当然,您可以将 varbinary 的大小设置为更高的值,以便将来进行升级。
建议您保留一个协议(protocol)编号以及您的 salt 和散列密码。这样做可以让您在以后的某个日期和每个条目升级该方案,当用户可以重置他/她的密码时。
要点; MSDN 没有指定生成盐的时间。我会检查 salt 的随机性(检查每次是否不同)并且只在调用 getBytes
后询问 salt 以确保 salt 确实是随机的,即使实现发生变化也是如此。否则使用加密安全随机数生成器自行生成。
关于c# - 使用 PBKDF2 加盐和散列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23169359/
我在 C# 中有以下代码 PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes,
是否有任何 python PBKDF (pkcs12) 实现?请注意,我不是在寻找 PBKDF1 或 PBKDF2 (pkcs5) 实现,而是在寻找 pkcs12 实现。正如本 question 中所
我是一名优秀的程序员,十分优秀!