Delphi中的密码加密

18

我需要将数据库密码存储在配置文件中。出于明显的原因,我想要加密它们(最好使用AES加密)。有没有人知道一个Delphi实现,可以轻松地引入到现有项目中,该项目具有超过10,000行历史代码(URGH!)?

澄清一下:易用性意味着将单元添加到项目中,在读取配置文件的地方添加最多5行代码,然后就完成了。不应花费超过15分钟。

另一个澄清:需要密码以便创建与数据库的连接,而不是为应用程序支持用户管理方案。所以使用哈希函数无济于事。数据库引擎检查密码是否有效,而不是应用程序。


哪种数据库?现在有比使用简单、旧的用户/密码对更好的连接方式。 - user160694
如果您正在使用Windows,则可以查看此文章:在Windows中安全存储密码的方法 - wittrup
15个回答

18

我赞同使用David Barton的DCPCrypt库的建议。 我已经在几个项目中成功使用它,而且只需要阅读使用示例,就不会花费超过15分钟。 它使用MIT许可证,因此您可以在商业项目和其他情况下自由使用它。 DCPCrypt实现了许多算法,包括Rijndael,即AES。

也有很多单元独立实现可以通过谷歌搜索到 - 问题在于你信任哪一个,除非你准备验证特定库的正确性。


3
DCPCrypt 很棒。我在很多地方都在使用它。 - gabr
1
说实话(在这么老的帖子里)我刚刚安装了 DCPcrypt,效果非常棒。 - dpant

15

对于典型的身份验证目的,您无需存储密码,只需检查用户输入的密码是否正确。如果是这种情况,那么您只需要存储哈希签名(例如MD5),然后将其与输入密码的签名进行比较。如果两个签名匹配,则输入的密码正确。

存储加密密码可能会很危险,因为如果有人获得您的“主”密码,则可以检索所有用户的密码。

如果您决定使用MD5,您可以使用Delphi自带的MessageDigest_5.pas(至少它包括在我的Delphi 2007副本中)。还有其他Delphi源代码实现可供选择。


4
谢谢你提到散列和存储密码的危险,顶赞(+1)。永远不要存储密码(甚至不要考虑加密!)。 - Jeroen Wiert Pluimers
3
如果他正在讨论存储数据库连接的密码,是否需要进行哈希处理?连接到数据库需要实际密码。或者您是建议将主数据库密码分发给所有用户以供其输入? - Eric G

8
我认为Turbopower LockBox是一个极好的加密库,尤其适用于IT技术领域: http://sourceforge.net/projects/tplockbox/ 我不知道它是否对你来说太大了,但它非常容易使用,你只需要写5行代码就可以加密一个字符串,所有的例子都在其中。

它已经过时且未得到维护。它不支持一些必要的改进(例如块密码、更大的密钥)。目前有更新它的努力,但现在它不是要使用的库。 - user160694

3

TurboPower LockBox 3 (http://lockbox.seanbdurkin.id.au/) 使用自动加盐。

我不建议使用Barton的DCPCrypt,因为它的IV没有被加盐。在某些情况下,这是一个非常严重的安全漏洞。

与早期评论相反,LB3对AES的实现完全符合标准。


  1. 版本3现在稳定了吗?
  2. 许可证已从Mozilla更改为GPL3,我想知道您是否有权这样做。许多商业开发人员更喜欢远离GPL库。
- user160694
  1. 请查看网站以获取状态信息;
  2. 不,那不正确。两个LockBox库中的任何一个都没有更改过许可证。LockBox 2是在MPL下发布的;LockBox 3是在LGPL3下发布的(而不是GPL)。LB2和LB3没有共同的源代码。没有商业开发者会放弃LGPL - 那只是不理智的行为。
- Sean B. Durkin

3

TOndrej的方法是正确的。您永远不应该使用可逆密码来存储密码。正如正确指出的那样,如果您的“主”密钥被攻破,整个系统都会受到影响。使用不可逆哈希,例如MD5,更加安全,您可以将哈希值存储为明文。只需对输入的密码进行哈希,然后将其与存储的哈希进行比较即可。


5
哈希处理不是选项,我需要密码才能与数据库建立连接。我完全无法控制数据库。 - Treb

3

2

2
即使你加密了,我认为你的解密密钥和加密密码都将在你的可执行文件中,这意味着它仅仅是一种安全性通过混淆。任何人都可以拿到解密密钥和加密密码,并生成原始密码。
你需要的是单向哈希。

1
单向哈希是理想的,但没有办法解密它以再次使用。听起来他需要读取密码,以便他的应用程序可以连接到数据库。如果您想要验证您之前存储的相同密码,则哈希值才有效。 - Jim McKeeth
哈希不是一个选项,我需要密码才能与数据库建立连接。我对数据库没有任何控制权。 - Treb
但是尼克是正确的。如果您将密钥存储到应用程序中,那么您只是让密码解密变得更加困难了一点点。您还需要保护密钥。 - user160694

1

提醒一下。

如果您不需要与其他加密库进行交互,那么DCP或LockBox就可以胜任。

但是

如果您需要完全符合rinjdael规范,那么请忘记免费组件,它们大多数时候都很“糟糕”。


1

正如其他人所指出的那样,为了身份验证目的,您应该避免使用可逆加密存储密码,即只应存储密码哈希值并检查用户提供的密码哈希与您存储的哈希是否相同。然而,这种方法有一个缺点:如果攻击者获取到您的密码存储数据库,它容易受到彩虹表攻击。

您应该做的是存储预先选择(和保密的)盐值+密码的哈希值。也就是说,将盐和密码连接起来,对结果进行哈希处理,然后存储此哈希值。在进行身份验证时,执行相同的操作-连接您的盐值和用户提供的密码,哈希,然后检查是否相等。这使得彩虹表攻击变得不可行。

当然,如果用户通过网络发送密码(例如,如果您正在开发Web或客户端服务器应用程序),则不应该以明文形式发送密码,因此,您应该存储并检查hash(salt + hash(password)),并让客户端对用户提供的密码进行预哈希处理,然后将其发送到网络上。这也保护了您的用户密码,因为许多用户会重复使用相同的密码。


1
哈希不是一个选项,我需要密码才能与数据库建立连接。我对数据库没有任何控制权。但是感谢你详细的解释! - Treb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接