这是在 Db 中加盐和存储密码的方法吗?
有几种方法(即使在SO中),它们都提到将密码保留在数据库上的最佳方法是保存,不是密码,不是哈希密码,而是存储加盐密码的哈希值。
我的问题很简单,放一些代码就可以了,这是正确的方法吗?
string username = "myUsr";
string password = "myPwd";
DateTime createDate = DateTime.UtcNow;
// Salt it
string saltedPwd = String.Concat(password, createDate.Ticks.ToString());
// Hash it
HMACSHA1 hash = new HMACSHA1(Encoding.Unicode.GetBytes(Helper.EncryptKey));
string encodedPwd = Convert.ToBase64String(
hash.ComputeHash(Encoding.Unicode.GetBytes(saltedPwd)));
// Create User in the database
db.CreateUser(username, encodedPwd, createDate);
数据库用户表
user_id | username | password | create_date | last_access | active
和登录使用时再次执行该过程,并检查encodedPwd
是否与提供的加盐、哈希密码相同。
我唯一关心的是,这是加盐密码的最佳方法吗?使用创建日期是否可以(因为它总是会改变,而且我读到最好始终使用不同的 <每次我们对密码进行编码时,code>salt...
或者salt
应该是一个完全不同的变量吗?
There are seveal ways (even here in SO) and they all mention that the best way to keep password on database is to save, not the password, not the hased password, but to store the hash of a salted password.
My question is simple, putting some code on it, is this the correct way?
string username = "myUsr";
string password = "myPwd";
DateTime createDate = DateTime.UtcNow;
// Salt it
string saltedPwd = String.Concat(password, createDate.Ticks.ToString());
// Hash it
HMACSHA1 hash = new HMACSHA1(Encoding.Unicode.GetBytes(Helper.EncryptKey));
string encodedPwd = Convert.ToBase64String(
hash.ComputeHash(Encoding.Unicode.GetBytes(saltedPwd)));
// Create User in the database
db.CreateUser(username, encodedPwd, createDate);
Database User Table
user_id | username | password | create_date | last_access | active
and upon Login use do the process again and check if the encodedPwd
is the same as the salted, hased password that was provided.
My only concern is, is this the best way to salt a password? Is it ok to use the Created Date (as that will always change, and I read that it is best to use always a different salt
every time we encode a password...
Or should be the salt
a completely different variable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您的实现可能足够好,但最好使用具有更多熵的盐:您当前使用的刻度值将始终在相对较小的范围内。
我建议使用类似 PBKDF2 的东西来为您完成工作,通过
Rfc2898DeriveBytes
:并进行身份验证...
Your implementation is probably good enough, but it would be better to use a salt with more entropy: the ticks value that you're currently using will always be in a relatively small range.
I would suggest using something like PBKDF2 to do the work for you, via
Rfc2898DeriveBytes
:And to authenticate...
我想知道为什么还没有人提到 BCrypt 。有一个现成的 C# 实现。请参阅http: //derekslager.com/blog/posts/2007/10/bcrypt-dotnet-strong-password-hashing-for-dotnet-and-mono.ashx
如果有适合您的经过验证的解决方案,请不要重新发明轮子问题。
I'm wondering why nobody has mentioned BCrypt yet. There is a ready to use implementation for C#. See http://derekslager.com/blog/posts/2007/10/bcrypt-dotnet-strong-password-hashing-for-dotnet-and-mono.ashx
Don't reinvent the wheel if there are proofed solutions for your issue.
您的方法完全没问题,但是假设有人获得了您的数据库,但没有获得您的代码库。他们基本上可以发现您只是将密码和创建日期连接起来,然后他们就可以对所有密码进行逆向工程。
您可能希望进一步注入一个仅存在于您的代码库中的唯一字符串,以获得一点额外的保护。
Your method is totally fine, but let's say someone got your database, but not your code base. They could essentially figure out that you simply concatenated the password and create date, and they could reverse engineer all passwords.
You may want to further inject a unique string that only exists in your code base for a little extra protection.
您尝试一下:
ProtectedData.Protect方法?
How about you try:
ProtectedData.Protect
method?我认为 CreateDate 的想法足够强大,但是当有人窃取您的数据库和代码时,您的盐就会暴露。基于“没有人可以篡改我的代码”的安全性是糟糕的安全性。
您可以简单地对密码进行双重散列...并使用第一次散列中的盐。
I think the idea with CreateDate is adequately powerful, but when someone steal your DB and Code, your salt is revealed. Security based on "nobody can snuff my code" is bad security.
You can simply double hash the password... And use salt from first hashing.