我正在使用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 ,它从密码派生字节。但是我需要有效的字符(Allowed character for SQL Server CE password?)来表示数据库密码,这意味着我可能无法使用 toBase64String()。
到目前为止,我的想法是为数据库创建一个随机安全的密码并将其保存到一个文件中,该文件将使用AES256加密,密钥来自用户密码。有没有更好的方法呢?
另外,我怎样才能实现那些拥有自己的应用程序密码的多个用户可以使用相同的数据库密码访问同一个数据库?
感谢您的时间和答案
答案 0 :(得分:2)
您无法直接执行此操作:将所有用户密码转换为相同数据库密码的函数将无法实现数据库加密。将DB密码存储在应用程序中是同形的。
这并不是说,没有一个简单的方法:
其中有一个简单的表格:
User | EncryptedPassword
(所有字符串)
对于每个用户在此文件中都有一行(如果是文本文件,则为一行),其中包含用用户密码加密的用户名和数据库密码(显然是pw的二进制哈希值,存储为base64) )
当用户登录时,使用给定的密码解密此用户的EncryptedPassword
字段,这应该是数据库密码,您现在可以使用该密码打开数据库
这也意味着,由于无法提供正确的SQL数据库密码而检测到错误的用户密码。
答案 1 :(得分:1)
在我看来,ToBase64String()
返回的字符串只包含字母,数字和斜杠。这符合SQL CE的要求。您可以使用Rfc2898DeriveBytes
,生成20个字节,然后从中生成一个40个字符的base64字符串。盐应该因用户而异 - 例如,您可以使用用户名和站点名称的串联。
答案 2 :(得分:0)
任何知道您的增强密码算法的人都可以重新应用该算法并使用弱用户密码攻击加密。在这方面,在密码中添加“某些东西”是一个好主意,但不是一个完美的解决方案。
通常,您所谈论的概念是salting。在对其进行散列之前,您需要输入其他数据(听起来像“不可恢复的”密码实际上是密码的散列)。它看起来(来自您提供的链接文章)密码用于连接字符串,这是限制您的有效字符集。
创建将密码存储为salted哈希的用户帐户时,应在服务器端确定salt值,并以与该用户关联的安全方式存储。在创建或更改密码时,每个用户的salt值应该包含在哈希算法中。
不使用单个中心密钥进行加密。只需将salt添加到用户提供的密码中即可。
<强>更新强>
如果您必须使用单个密码分发数据库,而不是使用特定于用户的密码(例如,如果您无法为每个用户单独加密副本),那么您有两个解耦的问题:
要处理第一个问题,请在应用程序中安全地嵌入相当长的密码。然而,对于坚定的攻击者来说,“安全嵌入”很难实现。在那里,你必须估计某人投入精力进入数据库的可能性(“电影列表”或“信用卡号码”?),并确定如果有人真的能够为你的公司或你的客户造成损失的可能性闯入(例如,你会“失去收入”给那些不会购买该程序的人,你是否会允许你的客户的秘密受到损害,......)。
如果您确定需要花费最多的精力来保护数据库密钥,请使用高端混淆解决方案。请注意,如果将AES加密的密钥存储在文件中,则代码仍需要解密加密数据以检索密钥。如果您的代码没有得到充分的监控,那么将某个调试器附加到您的程序并允许您的程序为其解密密钥是微不足道的,因此从这个意义上说AES几乎没有什么好处。但是,即使是最好的混淆也不会阻止最熟练和最坚定的黑客。
至于第二个要点,您需要授权用户访问您的程序(并间接访问数据库)。一种方法是使用简单的用户名/密码密码方法。您可以将Users表存储在SQL CE数据库中。毕竟,无论用户是否成功进行身份验证,程序都能够访问该数据库。