我正在尝试使用哈希和盐值来保存数据库中的密码,学习密码学知识,所以我决定制作一个登录系统来实现这个系统。
我的数据库包括:
- UserID int PK - Username varchar(250) - Salt varbinary(64) - Password varbinary(64) - RegDate datetime - Email varchar(250)
我正在使用PBKDF2,但似乎这不是哈希/盐值方法,如果不是,请问它是什么?
如果是这样,我做得对吗?
我的密钥:
我的数据库包括:
- UserID int PK - Username varchar(250) - Salt varbinary(64) - Password varbinary(64) - RegDate datetime - Email varchar(250)
我正在使用PBKDF2,但似乎这不是哈希/盐值方法,如果不是,请问它是什么?
如果是这样,我做得对吗?
我的密钥:
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。但这样做是否正确呢?这是否是哈希/盐值处理?
Rfc2898DeriveBytes
使用SHA-1。要检查密码是否正确,只需重新计算PBKDF2值并进行比较,无需进行其他加密。 - Maarten Bodewes