【问题标题】:How to avoid storing credentials to connect to Oracle with JDBC?如何避免存储凭据以使用 JDBC 连接到 Oracle?
【发布时间】:2010-09-12 16:58:00
【问题描述】:

是否可以在不在配置文件(或任何其他标准可读位置)中提供用户名/密码信息的情况下设置与 Oracle 的 JDBC 连接?

通常应用程序有一个配置文件,其中包含连接到数据库的设置参数。一些 DBA 对用户名和密码在配置文件中以明文形式存在这一事实存在疑问。

我认为这对于 Oracle 和 JDBC 是不可能的,但我需要一些确认...

一种可能的折衷方案是在配置文件中加密密码并在建立连接之前对其进行解密。当然,解密密钥不应该在同一个配置文件中。这只会解决未经授权的用户意外打开配置文件的问题。

【问题讨论】:

标签: oracle jdbc credentials


【解决方案1】:

您可能想尝试 Kerberos,它可以使用操作系统用户的凭据并将操作系统用户添加到外部识别的数据库中。确保您使用的是 Kerberos,而不是旧的方式,因为旧方式存在严重的安全问题。

为了支持 Kerberos,您需要高级安全选项和最新的 JDBC 驱动程序,可能是 11g 版本。在尝试让它在 Java 中工作之前,请在 Sql*Plus 中使用“/”作为用户名和空密码进行尝试。 “从双重选择用户”应该给你用户@域。您可能还会发现,在 Kerberos 配置方面,使用瘦驱动程序或 OCI 驱动程序之间存在根本区别。

【讨论】:

    【解决方案2】:

    您绝对不希望能够在没有凭据的情况下连接到数据库,因为这会使数据库容易受到攻击。

    这是一个普遍的问题,我如何存储访问外部系统所需的凭据? WebLogic 有一个凭证映射器来解决这个问题,其中凭证(加密的)存储在嵌入式 LDAP 中。许多 Oracle 产品使用将凭证存储在 Oracle 钱包中的凭证存储设施。

    在问题中,您提供了答案。存储密码加密并在需要时解密。显然,您必须使用对称加密算法(例如 3DES)才能解密它。确保对称密钥不是可以猜到的。

    诀窍在于保存加密/解密所需的对称密钥。您可以将其放在通过操作系统保护的文件中,也可以将其保存在代码中,但是您需要确保代码的安全。如果您使用能够生成相同密钥并且算法相当安全的技术,您也可以生成密钥。

    如果您可以确保代码安全,那么您显然也可以将密码保存在代码中。但是,您希望能够在不更改代码的情况下更改凭据的灵活性。

    您也可以在此解决方案中添加更多层。您可以加密配置文件(使用不同的密钥)以及其中的密码,使黑客发现 2 个密钥。还有其他更安全的方法使用 PKI,但它们很难设置。

    【讨论】:

      【解决方案3】:

      我建议您研究一下代理身份验证。这记录在Oracle® Database Security GuideOracle® Database JDBC Developer's Guide and Reference 中。本质上,这允许您做的是在数据库中拥有一个仅具有连接权限的用户。用户真实数据库帐户被配置为能够以代理用户身份连接。通过 JDBC 连接的应用程序然后存储代理用户名和密码,并在连接时提供这些凭据,并在连接字符串中加上真实数据库用户的用户名。 Oracle 以代理用户身份连接,然后模仿真实数据库用户,继承真实用户的数据库权限。

      【讨论】:

      • 这种做法不是让安全性更差吗?知道代理用户名+密码的攻击者可以访问任何这些真实帐户下的数据库。这就是为什么我提出使用证书(希望由操作系统安全管理)而不是用户名+密码来通过代理进行身份验证。
      • 您仍然需要保护代理用户名和密码。但它可以让您控制中间层可以连接的用户,以及中间层可以为用户承担的角色。
      • 感谢您的信息!我自己从来没有使用过这个功能。您是否碰巧知道 JDBC 层是否可以安全地访问操作系统管理的证书。如果这是可能的,该方法会比代理用户名+密码更好,因为证书会粘在机器上。
      • 我不是 100% 确定,但文档的这一部分是您检查的最佳选择 -> download.oracle.com/docs/cd/B19306_01/java.102/b14355/…
      【解决方案4】:

      所有J2EE 容器(JBOSSTomcatBEA)都有连接池。他们将打开许多连接,使它们保持活动状态,并在1/100th 内将它们提供给您,而这正是从头开始创建连接所需的时间。

      此外,它们还具有很酷的功能,例如在JBOSS 中,所有连接信息都存储在外部文件中。如果您更改连接信息,即从 test 切换到 production DB,您的应用程序将动态地从新池中获取连接

      好消息是,您无需运行完整的J2EE 容器即可使用连接池。外部资源允许密码以明文或伪加密形式存储。

      有关使用 Tomcat 的内置连接池的指南,请参阅 apache commons-dbcp:

      【讨论】:

        【解决方案5】:

        据我所知,jdbc 连接用户名/密码需要以纯文本形式存储。限制这种可能风险的一种方法是限制用户的权限,以便只能使用给定的应用程序数据库并且只能来自预定义的主机。 IMO,这将极大地限制攻击者:他只能使用来自原始应用程序所在同一主机的 un/pw 并且只能攻击原始应用程序的数据库。

        【讨论】:

        • 将密码存储为纯文本违反了所有标准安全实践。
        • 是的,这是一个问题,但是在这种情况下,解决方案是什么?
        【解决方案6】:

        过去曾想过这个问题。

        该解决方案当然包括在服务器和网络级别具有适当的网络安全性,以真正减少可以访问系统的人数,并且拥有数据库凭据仅允许访问数据库帐户应用程序运行所需的最低权限。

        对属性文件进行加密可能足以起到威慑作用,因为“不必费心去寻找密钥或密码”让攻击者进入下一个被入侵的服务器。但是,我不会依赖“我的邻居不太安全,所以请从他那里偷走”安全!

        【讨论】:

          【解决方案7】:

          有两种关键方法,它们都对系统的设计产生重大影响,因此在不进行重大重写的情况下从一种方法转移到另一种方法并不容易。在选择之前,您需要了解您公司的安全治理政策。

          1) 每个用户都有通过应用程序携带的凭据,用于应用程序正在使用的服务;在您的情况下,Oracle 数据库使用这些用户凭据连接到数据库。缺点是每个用户都需要每个安全服务的凭据。这是一种合理的安全方法,但也需要大量额外的工作来提供和维护用户凭据。您的数据库管理员将需要主动管理用户凭据,这可能与您公司的安全治理策略背道而驰。

          2) 应用程序数据库凭据存储在安全目录服务中,例如安全 LDAP。应用程序使用用户的凭据访问目录服务。目录服务返回正在访问的服务的适当凭据。

          在这两种情况下,应将数据库凭据限制为仅执行适当的操作。凭证应反映业务流程的要求,例如;它们允许从定义的视图/表中选择、插入到其他视图中,但不能创建、更新或删除表。在第二种方法中,为每个主要业务流程使用单独的凭据,例如订单处理、会计、人力资源等。

          但是请记住,安全性就像洋葱的层,如果有人剥离了层来访问应用程序,这样他们就可以访问数据库连接池配置文件。他们可能会特洛伊木马应用程序来捕获用户的凭据。这就是良好的安全治理策略的用武之地。

          安全治理是一个复杂的问题,需要高级管理层的承诺,因为如果您需要为您的实时平台提供这种级别的安全性,则需要付出代价。您需要将开发职责与部署、操作和用户权限管理分开。您可能还需要有安全审计员,他们具有查看更改的完全访问权限,但无法更改配置。它远非简单,而且是高薪专业。

          【讨论】:

          • 对于上下文,此解释假设一个离散的用户社区将直接和个人与 Oracle 数据库进行交互(例如公司中的业务用户)。这与基于 Web 的应用程序的通用范例(我认为问题的作者假设)形成对比,其中应用程序或 Web 服务器始终使用相同的凭据连接到数据库,并且通过应用程序代码处理安全问题,而不是数据库级别的访问控制。
          【解决方案8】:

          由于除了 Java 和 JDBC 与 Oracle 交谈之外,我对您的环境并不完全清楚,因此我将对此进行讨论。

          如果您谈论的是 Java EE 应用程序,您应该能够在应用程序服务器上设置连接池和数据源,然后您的应用程序会与在该级别处理连接的连接池进行通信。

          连接池和数据源保存并保护凭据。

          【讨论】:

          • 那你如何通过连接池进行认证呢?否则,您基本上没有安全性。还不如在 oracle 帐户上没有密码。
          【解决方案9】:

          您可以将凭据存储在任何地方,包括作为程序中的硬连线字符串或 Windows 注册表中的条目。但是,如果您使用非标准的东西,则由您来检索它们;我不知道有任何非纯文本的预推出解决方案。

          【讨论】:

            【解决方案10】:

            您可以尝试 Oracle 的代理身份验证,其中 JDBC 客户端使用证书对数据库服务器信任的已知中间层组件/服务(代理)进行身份验证。不过我从来没有尝试过,所以我不知道它是否容易做到。

            【讨论】:

              【解决方案11】:

              除了已经提到的解决方案(Kerberos 身份验证,使用代理身份验证)之外,还有 2 个其他解决方案都可以与 JDBC 瘦驱动程序一起使用:

              1. 将密码存储在 SSO 钱包中:可以使用钱包来存储用户的密码。如果您使用 SSO 钱包,则钱包本身没有密码。 SSO 钱包通常用于 SSL 的上下文中,但它们也可用于仅存储密码。
              2. 将 SSL 与用户身份验证一起使用:使用通过专有名称 (DN) 进行外部身份验证的用户配置 SSL。此用户没有密码。只要您使用具有此 DN 的证书连接 SSL,您就可以使用此用户创建会话。

              【讨论】:

                猜你喜欢
                • 2018-01-30
                • 1970-01-01
                • 2021-05-16
                • 1970-01-01
                • 2017-03-25
                • 2015-03-16
                • 2016-09-29
                • 2012-12-21
                • 2023-03-06
                相关资源
                最近更新 更多