Storing a password in a string before sending to database
我想学习一些处理密码的好方法。我将从我的项目中提供一些代码片段,并解释我担心和好奇的事情。
让我们从获取用户输入的代码开始,我的按钮事件代码:
1 2 | string username = txtUser.Text; string password = Hash.EncryptString(txtPass.Text); |
在这里,我的想法是,将密码以明文形式存储在字符串中可能是不好的做法?我知道这可能不是解决这个问题的方法(特别是因为我将它以明文发送给另一个方法,然后将它存储在一个字符串中),但这里我调用了一个我创建的方法来将密码转换为哈希。"hash"类中的encryptString方法:
1 2 3 4 5 6 7 8 9 10 11 12 | public static string EncryptString(string text) { var sha1 = System.Security.Cryptography.SHA1.Create(); var inputBytes = Encoding.ASCII.GetBytes(text); text =""; //clear string var hash = sha1.ComputeHash(inputBytes); var sb = new StringBuilder(); for (var i = 0; i < hash.Length; i++) sb.Append(hash[i].ToString("X2")); return sb.ToString(); } |
号
这里没什么好说的,我用sha1加密对密码进行了散列。我认为在我使用后清除字符串是明智的,这样密码就不会再被存储了?
稍后在验证或添加用户的代码中,我将获取或创建一个惟一的salt,并将其与哈希密码混合,然后再次使用encryptString方法,然后再进入数据库。
以隐私和安全的名义,这是一个好的做法吗?或者更确切地说,目前我的代码中存在哪些漏洞,如何修复它们?
这里有两个问题:
让我们来解决这两个问题:
(1)许多安全人员会推荐SecureString来保护您的堆内存。然而,事实证明,SecureString并没有广告中的那么好。如果你想知道原因,你可以在YouTube上观看这个SecureString设计评论。它很长,但是很好,你只需要看10到15分钟就可以看到问题所在。
在Web应用程序的特定上下文中,您可以尝试各种特技,以防止明文密码在内存中,但在一天结束时,您将对象作为一个字符串从请求对象中获取。您无法控制该请求对象的垃圾收集。在你把手放在上面之后,试图保护你的记忆,就像把创可贴放在筛子上一样。
底线:别担心。您无法解决框架固有的问题。
(2)您对密码存储的想法正落在前10位开发者密码错误中的第4位。
特洛伊亨特有一篇优秀的文章,介绍了访问数据库的人如何破解密码,以及如何使用bcrypt或pbkdf2(bcrypt更好)来防止此类攻击。
你想防范什么情况?您在这里面临的主要威胁是包含字符串密码的内存转储,或其他内存分析调试工具。现在,这可能是一个合法的威胁,也可能不是,取决于更多的上下文。但是,如果
注意:
1 | text =""; //clear string |
不从非托管堆中移除字符串。它只是将名为