42

我有一个数据库,许多不同的客户端应用程序(少量 Web 服务、一些 Java 应用程序和一些 dot net 应用程序)都连接到该数据库。并非所有这些都在 Windows 上运行(遗憾的是,否则只需为数据库连接启用 Windows 身份验证,这将成为一个简单的答案问题)。目前,密码存储在系统周围的各种配置/属性文件中。理想情况下,只有支持人员才能访问运行文件的服务器,但如果其他人获得对其中一台服务器的访问权限,他们将拥有足够的数据库权限来获得相当多的数据,就像现在这样。

那么我的问题是,保持密码可配置的最佳方法是什么,而不是让普通的人类读者太容易获得它?

编辑只是为了澄清,数据库服务器是 Windows Server 2003,运行 MSSQL 2005。

PS:我没有看到任何重复的问题,但如果有,请随时关闭此问题。

4

11 回答 11

17

我假设您想对不经意的观察者隐藏密码。如果他们是邪恶的、目光敏锐的观察者,可以访问其中一台连接的机器上的所有源代码,那么他们可以通过一些逆向工程来获取密码。

请记住,您不需要为每个不同的客户端使用相同的保护。几个步骤:-

  1. 为访问您的数据库的不同系统创建不同的数据库帐户
  2. 使用您的内置数据库 GRANT 将数据库的访问权限限制在他们需要的范围内
  3. 在数据库的密码管理器类中存储三重 DES(或其他)密钥。使用它来解密属性文件中的加密值。

我们还考虑过在启动时让应用程序提示输入密码,但尚未实施,因为这似乎很痛苦,您的操作人员需要知道密码。它可能不太安全。

于 2008-11-03T11:07:50.767 回答
10

让我们假设以下常见情况:

  • 您对所有环境使用相同的代码库,并且您的代码库具有每个环境的数据库密码。

  • 有权访问您的生产应用程序服务器的人员(系统管理员、配置管理员)被允许知道生产数据库密码,而其他任何人都不知道。

  • 您不希望任何有权访问源代码的人知道生产密码是什么。

在这种情况下,您可以加密生产密码并将其存储在应用程序的属性文件中。在应用程序中,您可以包含一个类,该类从属性文件中读取密码并在将其传递给数据库驱动程序之前对其进行解密。但是,用于解密密码的密钥和算法不是源代码的一部分,而是在运行时作为系统属性传递给应用程序。这将密钥知识与应用程序源代码分离,任何只能访问应用程序源代码的人将不再能够解密密码,因为他们无权访问应用程序的运行时环境(应用服务器)。

如果您使用的是 Java,请查看这个以获取更具体的示例。该示例使用 Spring 和 Jasypt。我相信这样的事情可以外推到其他环境,如 .Net

于 2009-01-07T19:18:58.290 回答
4

在我以前的工作场所,我们曾经有一个系统,所有密码都被加密(使用三重 DES 或我们当时使用的任何东西)。密码通常存储在属性文件中(这是在 Java 系统中)。

当需要更改密码时,我们可以简单地使用“!plaintext”作为值,然后我们的代码会加载它,对其进行加密,并将加密后的值存储回属性文件中。

这意味着可以在不知道原始值的情况下更改密码 - 不确定这是否是您要求的那种东西!

于 2008-11-03T10:50:13.983 回答
3

听起来没有简单的答案(因为连接的应用程序类型不同)......真的,我看到的唯一问题是 Java 应用程序似乎直接连接到您的数据库。那是对的吗?

如果是这样,您可以执行以下操作:

1) 更改任何直接连接到数据库的客户端应用程序以通过服务。(如果他们必须直接连接,那么至少给他们一个从服务“获取密码”的第一步,然后他们可以直接连接)。

2) 将密码存储在 web.config 文件中(如果您选择使用 .Net Web 服务),然后加密文件的“连接字符串”部分。

于 2008-11-03T10:51:01.797 回答
2

不要使用密码,服务器到服务器的身份验证通常可以通过使用密钥文件或客户端证书或密码以外的其他方式来执行。

于 2008-11-03T10:42:31.050 回答
0

您可以使用可逆加密算法(例如 Blowfish)来存储密码作为权宜之计。应该有许多免费库可以用来将其构建到所有需要此访问权限的程序中。

Bruce Schneier 关于河豚的页面

维基百科关于河豚的文章

于 2008-11-03T10:48:41.723 回答
0

对于 java 的东西,如果您使用的是应用程序服务器,请查看是否可以定义数据源,并且您的应用程序可以使用 JNDI 获取数据源。这样,管理数据源(包括连接详细信息)由应用服务器处理,您的应用程序代码要做的就是请求数据源。

于 2008-11-03T11:16:53.400 回答
0

NTLM 身份验证或基于 LDAP (Active Directory) 的身份验证应该提供给您稍作努力。这将允许您跨应用程序使用“Windows 身份验证”。

这可能意味着您的操作人员需要进行一些迁移,但是对于一组应用程序来说,SSO 是不错的选择。

于 2008-11-03T12:50:17.360 回答
0

是的,我必须同意存储(盐渍)哈希的选项。我会推荐存储在数据库中的密码的(加盐的)SHA256 哈希。也不要忘记强制执行安全密码规则。

于 2009-10-18T02:46:22.367 回答
0

我对您的问题的解释是,您具体询问如何存储配置密码,您的代码将使用这些配置密码连接到它所依赖的服务,例如数据库或第三方 API。在这种情况下,您可能需要考虑使用提供秘密容器的服务,例如Hashicorp 的 Vault

您可以将 Vault 视为您的应用程序可以连接到的 Web 服务,以便在应用程序运行时查找您的应用程序所需的秘密。

例如,假设您的应用程序需要连接到数据库,但您不想将数据库凭据与应用程序源代码一起存储在版本控制系统中。此外,假设您希望应用程序使用的数据库凭据在每次应用程序启动时都不同。在这种情况下,您可以在 Vault 中启用和配置数据库机密后端。这意味着保险库将动态创建您的数据库凭据作为服务,然后在一段时间内为您的应用程序提供可撤销的租用令牌。当然,保险柜将允许您在其中存储任何秘密。

Vault 为您的应用程序连接到它提供了安全的方式。一种这样的身份验证方法使用保险库中称为Cubbyhole Secrets Engine的东西。

于 2020-04-25T17:27:30.443 回答
-2

使用加密不是一个好主意。如果有人泄露了密钥,他可以解密它。使用带盐的哈希算法来存储密码。哈希算法是一种方式,因此它是不可逆的。但是它们很容易受到字典攻击,因此请使用盐(连接纯文本,其内容长而冗长,而不是散列)。它还保护数据库免受内部攻击。

于 2009-06-18T20:35:55.490 回答