我需要将数据库密码存储在配置文件中。出于显而易见的原因,我想对它们进行加密(最好使用 AES)。有谁知道一个 Delphi 实现,它很容易引入到具有超过 10,000 行历史增长(URGH!)源代码的现有项目中?
澄清:简单意味着将单元添加到项目中,添加最大值。读取配置文件并使用它完成的 5 行代码。时间不应超过 15 分钟。
另一个说明:需要密码才能创建与数据库的连接,而不是支持应用程序的用户管理方案。所以使用哈希没有帮助。数据库引擎检查密码是否有效,而不是应用程序。
我需要将数据库密码存储在配置文件中。出于显而易见的原因,我想对它们进行加密(最好使用 AES)。有谁知道一个 Delphi 实现,它很容易引入到具有超过 10,000 行历史增长(URGH!)源代码的现有项目中?
澄清:简单意味着将单元添加到项目中,添加最大值。读取配置文件并使用它完成的 5 行代码。时间不应超过 15 分钟。
另一个说明:需要密码才能创建与数据库的连接,而不是支持应用程序的用户管理方案。所以使用哈希没有帮助。数据库引擎检查密码是否有效,而不是应用程序。
我支持 David Barton 的DCPCrypt library的推荐。我已经在几个项目中成功使用过,阅读使用示例后不会超过 15 分钟。它使用 MIT 许可证,因此您可以在商业项目和其他项目中自由使用它。DCPCrypt 实现了许多算法,包括 AES 的 Rijndael。
也有许多可谷歌搜索的独立(单单元)实现 - 问题是您信任哪一个,除非您准备好自己验证特定库的正确性。
对于典型的身份验证目的,您不需要存储密码,您只需检查用户输入的密码是否正确。如果这是您的情况,那么您可以只存储一个哈希签名(例如 MD5)并将其与输入密码的签名进行比较。如果两个签名匹配输入的密码是正确的。
存储加密密码可能很危险,因为如果有人获得您的“主”密码,他们可以检索您所有用户的密码。
如果您决定使用 MD5,您可以使用 Delphi 附带的 MessageDigest_5.pas(至少它包含在我的 Delphi 2007 副本中)。Delphi 源代码还有其他实现可供您选择。
我认为 Turbopower LockBox 是一个出色的文字库:
http://sourceforge.net/projects/tplockbox/
我不知道它是否对你的使用来说太大了,但它非常易于使用,你可以用 5 行代码加密一个字符串。这一切都在示例中。
TOndrej 有正确的方法。您永远不应该使用可逆密码存储密码。正如正确指出的那样,如果您的“主”密钥被泄露,则整个系统都会被泄露。使用不可逆散列(例如 MD5)更加安全,您可以将散列值存储为明文。只需对输入的密码进行哈希处理,然后将其与存储的哈希值进行比较。
我一直使用 Turbopower Lockbox。它运行良好,而且非常易于使用。我实际上将它用于完全相同的事情,将密码存储在配置文本文件中。
TurboPower LockBox 3 (http://lockbox.seanbdurkin.id.au/) 使用自动加盐。我建议不要使用 Barton 的 DCPCrypt,因为 IV 没有加盐。在某些情况下,这是一个非常严重的安全漏洞。
与之前的评论相反,LB3 的 AES 实现完全符合标准。
即使您加密了,在我看来,您的解密密钥和加密密码都将在您的可执行文件中,这意味着绝不是默默无闻的安全。任何人都可以获取解密密钥和加密密码并生成原始密码。
你想要的是一个单向哈希。
只是提醒。
如果您不需要与其他 crypt 库进行互操作,那么 DCP 或 LockBox 就可以完成这项工作。
但
如果您需要它完全符合 rinjdael 规范,请忘记免费组件,它们大多数时候有点“糟糕”。
正如其他人所指出的,出于身份验证的目的,您应该避免使用可逆加密存储密码,即您应该只存储密码哈希,并根据您存储的哈希检查用户提供的密码的哈希。但是,这种方法有一个缺点:如果攻击者掌握了您的密码存储数据库,它很容易受到彩虹表攻击。
您应该做的是存储预选(和秘密)盐值 + 密码的哈希值。即,连接盐和密码,散列结果,并存储这个散列。进行身份验证时,请执行相同的操作 - 连接您的盐值和用户提供的密码、哈希,然后检查是否相等。这使得彩虹表攻击不可行。
当然,如果用户通过网络发送密码(例如,如果您正在使用 Web 或客户端-服务器应用程序),那么您不应该以明文形式发送密码,而不是存储散列(salt +密码)您应该存储并检查哈希(盐+哈希(密码)),并让您的客户端对用户提供的密码进行预哈希并通过网络发送该密码。这也可以保护您的用户密码,以防用户(许多人)将相同的密码用于多种用途。
我建议使用某种盐。不要将 crypt(password) 存储在配置文件中,而是插入此存储 crypt(salt + password)。作为“盐”,您可以使用打开数据库所需的东西,例如。db_name+user_name。对于 crypt 函数,您可以使用一些众所周知的算法,如 AES、Idea、DES,或者像将每个字节与其他字符串中的字节进行异或运算一样简单,该字符串将成为您的密钥。为了使其解决起来更加不同,您可以使用一些随机字节并存储它们。
所以要存储:
并连接:
尼克当然是对的——当你说你想花 15 分钟来实施安全解决方案时,我只是假设你知道自己在做什么。如果您决定采用(更好的)路线,DCPCrypt 库还实现了许多散列算法。
几个解决方案:
这个 Embarcadero 的演示给出了一个简单但对于大多数应用程序来说足够强大的系统: https ://edn.embarcadero.com/article/28325