保持密码可配置的最佳方法是啥,而不会让普通的人类读者太容易获得它们?

Posted

技术标签:

【中文标题】保持密码可配置的最佳方法是啥,而不会让普通的人类读者太容易获得它们?【英文标题】:What is the best way to keep passwords configurable, without having them too easily available to the casual human reader?保持密码可配置的最佳方法是什么,而不会让普通的人类读者太容易获得它们? 【发布时间】:2010-09-20 11:22:13 【问题描述】:

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

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

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

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

【问题讨论】:

有一个非常相似的问题:***.com/questions/126720/… 哦,它没有显示我用于搜索的任何单词。如果你想关闭问题,你可以。 【参考方案1】:

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

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

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

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

【讨论】:

正确,主要是为了阻止不经意的观察者。 WRT到你的观点:1)完成。 2) 完成。 3)有趣的想法。可能值得测试谢谢 你是说没有绝对的办法? @Khnle-KevinLe 如果有人可以访问所有建立连接的软件,那么您对他们没有任何秘密。你只会让事情变得更难找到。【参考方案2】:

让我们假设以下常见场景:

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

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

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

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

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

【讨论】:

【参考方案3】:

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

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

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

【讨论】:

【参考方案4】:

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

如果是这样,您可以这样做:

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

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

【讨论】:

是的,一些 java 系统确实直接连接到数据库。这是一个非常有机地发展的旧系统。但这些都是一些很好的建议。谢谢 客户端-服务器应用程序是最佳选择。服务不应该使用数据库密码,因为您会遇到同样的问题。所有服务都应该通过 java 服务器可用,没有桌面应用程序应该直接连接到数据库。【参考方案5】:

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

【讨论】:

1) 这不适用于桌面应用程序,因为这意味着它捆绑了证书。 (2) 有人可以获得证书,就像有人可以访问源代码一样。【参考方案6】:

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

Bruce Schneier 在Blowfish 上的页面

关于Blowfish的***文章

【讨论】:

【参考方案7】:

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

【讨论】:

【参考方案8】:

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

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

【讨论】:

明确指出不是所有的都在windows上运行。非 Windows 客户端上的 LDAP 可能很麻烦。【参考方案9】:

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

【讨论】:

您正在考虑用户的密码。这是数据库密码本身 - 必须可逆地存储。【参考方案10】:

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

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

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

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

【讨论】:

【参考方案11】:

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

【讨论】:

您正在考虑用户的密码。这是数据库密码本身 - 必须可逆地存储。

以上是关于保持密码可配置的最佳方法是啥,而不会让普通的人类读者太容易获得它们?的主要内容,如果未能解决你的问题,请参考以下文章

硬盘逻辑分区应该怎么排序,物理顺序是啥,怎样让C盘保持在最佳顺序上

在 PHP 中保持 MySQL 凭据私有的最佳方法是啥?

将带有单位的数字转换为非人类可读格式

在 git 存储库中处理密码的最佳实践是啥?

除了几个屏幕之外,在整个应用程序中保持 UIView 的最佳方法是啥?

在 Rails 3 中删除表和删除模型的最佳方法是啥?