从(多个)用户输入(应用程序密码)中派生数据库的密码
本文关键字:密码 派生 数据库 输入 多个 用户 应用程序 | 更新日期: 2023-09-27 18:30:15
我正在使用C#(.NET 4.0,SQL CE 4.0数据库)编写一个小型企业应用程序。数据库是加密的(SQL CE支持数据库加密),但据我所知,从 http://msdn.microsoft.com/en-us/library/aa257373(v=sql.80).aspx密码:
最长可达 40 个字符。 可以包含字母、符号、数字或组合。 无法恢复。
我的用户将为应用程序输入密码,这可能不是很复杂和安全。因此,我想以某种方式修改用户密码,为数据库加密创建更安全的密码。 据我所知,有Rfc2898DeriveBytes Class,它从密码派生字节。但是我需要有效字符(SQL Server CE 密码允许的字符?)作为数据库密码,这意味着我可能无法使用 toBase64String()。
到目前为止,我的想法是为数据库创建一个随机且安全的密码,并将其保存到一个文件中,该文件将使用AES256进行加密,密钥来自用户密码。有没有更好的方法可以做到这一点?
另外,我如何实现多个用户(每个用户都有自己的应用程序密码)可以使用相同的数据库密码访问同一数据库?
感谢您的时间和答案
您不能直接执行此操作: 将所有用户密码转换为相同数据库密码的函数将违背数据库加密的目的。它与在应用程序中存储数据库密码是同构的。
这并不是说,没有一个简单的解决方法:
- 有第二个文件 - 未加密的 SQL CE 数据库或纯文本文件
-
里面有一个简单的表格:
User | EncryptedPassword
(所有字符串) -
对于每个用户,此文件中都有一行(如果是文本文件,则为一行),其中包含用户名和密码使用用户密码加密的数据库密码(显然是 pw 的二进制哈希,存储为 base64)
-
当用户登录时,使用给定的密码解密该用户的
EncryptedPassword
字段,这应该是数据库密码,您现在可以使用它来打开数据库 -
这也意味着,由于未能提供正确的 SQL 数据库密码,则会检测到错误的用户密码。
,ToBase64String()
返回一个仅由字母、数字和斜杠组成的字符串。 这符合 SQL CE 的要求。您可以使用 Rfc2898DeriveBytes
,生成 20 个字节,然后从中生成一个 40 个字符的 base64 字符串。 盐应该因用户而异 - 例如,您可以使用用户名和站点名称的串联。
任何知道您的增强密码算法的人都可以重新应用该算法并使用弱用户密码攻击加密。 在这方面,在密码中添加"某些东西"是一个好主意,但不是一个完美的解决方案。
一般来说,你所说的概念是盐渍。 在对输入进行哈希处理之前,您可以使用其他数据进行加盐输入(听起来"不可恢复"密码实际上是密码的哈希值)。 看起来(从您提供的链接文章中)密码在连接字符串中使用,这是限制有效字符集的原因。
创建将密码存储为加盐哈希的用户帐户时,应在服务器端确定盐值,并以安全的方式存储,与该用户相关联。 创建或更改密码时,应将每用户盐值合并到哈希算法中。
不要使用单个中央密钥进行加密。 只需在用户提供的密码中添加盐即可。
更新
如果必须使用单个密码而不是用户特定的密码分发数据库(例如,如果无法为每个用户单独加密副本),则有两个分离的问题:
- 如何保护数据库不被未经授权的人查看?
- 如何对我的用户进行身份验证?
处理第一个问题,在应用程序中安全地嵌入一个相当长的密码是要走的路。 然而,"安全嵌入"很难对付坚定的攻击者。 在那里,你必须估计某人投入精力闯入数据库("电影列表"或"信用卡号")的可能性,并确定如果有人真的能够闯入,你的公司或你的客户会遭受损失(例如,你会"失去收入"给一个无论如何都不会购买该程序的人吗? 您是否允许客户的机密被泄露,...
如果确定需要使用最大工作量来保护数据库密钥,请使用高端模糊处理解决方案。 请注意,如果将密钥 AES 加密存储在文件中,则代码仍需要解密加密的数据才能检索密钥。 如果您的代码没有很好地混淆,那么有人将调试器附加到您的程序并允许您的程序为他们解密密钥是微不足道的,因此从这个意义上讲,AES 几乎没有提供什么好处。 但是,即使是最好的混淆也无法阻止最熟练和最坚定的黑客。
至于第二个要点,您需要授权用户访问您的程序(并间接访问数据库)。 一种方法是使用简单的用户名/密码哈希方法。 可以将"用户"表存储在 SQL CE 数据库中。 毕竟,无论用户是否成功进行身份验证,程序都将能够访问该数据库。