代码之家  ›  专栏  ›  技术社区  ›  AshtonKJ

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

  •  43
  • AshtonKJ  · 技术社区  · 17 年前

    我有一个数据库,许多不同的客户端应用程序(少量web服务、一些java应用程序和一些点网络应用程序)都连接到该数据库。并非所有这些都在windows上运行(可悲的是,否则只需为数据库连接启用windows身份验证,这将是一个容易回答的问题)。目前,密码存储在系统周围的各种配置/属性文件中。理想情况下,只有支持人员可以访问运行文件的服务器,但如果其他人可以访问其中一台服务器,他们将有足够的数据库权限来获得目前的数据。

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

    编辑 为了澄清一下,DB服务器是运行MSSQL 2005的Windows server 2003。

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

    11 回复  |  直到 13 年前
        1
  •  17
  •   WW.    17 年前

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

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

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

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

        2
  •  10
  •   neesh    17 年前

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

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

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

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

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

    如果您正在使用Java,请查看 this 举一个更具体的例子。该示例使用Spring和Jasypt。我相信,这样的事情可以推断到其他环境中。网

        3
  •  4
  •   user7094 user7094    17 年前

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

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

    这意味着可以在不知道原始值的情况下更改密码——不确定这是否是你想要的东西!

        4
  •  3
  •   Timothy Khouri    17 年前

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

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

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

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

        5
  •  2
  •   paan    17 年前

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

        6
  •  0
  •   Bork Blatt    17 年前

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

    布鲁斯·施奈尔的页面 Blowfish

    维基百科文章 Blowfish

        7
  •  0
  •   tunaranch    17 年前

    对于java内容,如果您使用的是应用程序服务器,请查看是否可以定义数据源,您的应用程序可以使用JNDI访问数据源。这样,管理数据源(包括连接细节)由应用程序服务器处理,您的应用程序代码所要做的就是请求数据源。

        8
  •  0
  •   Ken Gentle    17 年前

    只需稍加努力,您就可以使用NTLM身份验证或基于LDAP(Active Directory)的身份验证。这将允许您在应用程序之间使用“windows身份验证”。

    这可能意味着您的运营人员需要进行一些迁移,但一组应用程序的SSO是很好的。

        9
  •  0
  •   meme    16 年前

    是的,我必须同意存储(盐)哈希的选项。我建议使用存储在数据库中的SHA256哈希值。另外,不要忘记执行安全密码规则。

        10
  •  0
  •   axiopisty    6 年前

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

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

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

    Vault为您的应用程序提供了安全的连接方式。其中一种身份验证方法使用Vault中称为 Cubbyhole Secrets Engine .

        11
  •  -2
  •   Gok Demir    17 年前

    使用加密不是一个好主意。如果有人压缩了密钥,他就可以解密它。使用带有盐的哈希算法来存储密码。哈希算法是一种方法,因此它是不可逆的。但是它们很容易受到字典攻击,所以使用salt(具体的纯文本,有一些长而冗长的东西,而不是哈希)。它还可以保护数据库免受内部攻击。