【问题标题】:Set JRE to use Windows trust store, specifically the user's trust store将 JRE 设置为使用 Windows 信任库,特别是用户的信任库
【发布时间】:2018-08-16 23:59:57
【问题描述】:

总结:Java 选项 -Djavax.net.ssl.trustStoreType=WINDOWS-ROOT 允许 Java 为 计算机帐户使用 Windows 信任库。 什么选项允许它为 用户帐户使用 Windows 信任库?

我们有一个在 Windows 客户端上运行的 Java 应用程序。应用程序从各种来源获取数据,其中一些使用不在默认cacerts 文件中的证书。

当用户选择访问外部数据的项目时,系统会提示他们下载外部站点的证书。由于我们的安全设置,cacerts 文件对用户是只读的。因为 JRE 无法将证书导入cacerts,所以外部不会下载。并且一遍又一遍地提示用户下载证书。

当用户被授予对cacerts 的写入权限时,不会出现此问题。但是我们的安全团队不允许我们向普通用户授予对该文件的写入权限。他们的政策是,C: 驱动器上的任何文件,除了用户自己的配置文件之外,都不应该是读写的。

我们认为我们找到了让 Java 使用 Windows 信任库的解决方法。我们在启动脚本中添加了标志-Djavax.net.ssl.trustStoreType=WINDOWS-ROOT。这迫使 Java 使用用户可以写入的 Windows 信任存储。

很遗憾,用户只能写入他们的证书存储区,而不能写入计算机的证书存储区。当我们以管理员身份运行应用程序时,证书被导入到计算机的存储中。之后,不会提示普通用户下载证书。但是,如果我们不以管理员权限运行一次,则不会导入证书,因为 Java 会尝试写入 Windows 计算机帐户 存储,该存储与cacerts 一样被锁定.

是否有一个标志强制 Java 使用整个 Windows 信任存储,而不仅仅是计算机帐户的存储?

【问题讨论】:

    标签: java windows ssl certificate truststore


    【解决方案1】:

    除了javax.net.ssl.trustStoreType=Windows-ROOT,我还必须定义javax.net.ssl.trustStore=NUL才能在Windows上运行,即使println(System.getProperty('javax.net.ssl.trustStore'))打印了null。另见https://newbedev.com/import-windows-certificates-to-java

    由于 Gradle 需要这个,我必须将以下内容添加到我的 gradle.properties

    systemProp.javax.net.ssl.trustStore=NUL
    systemProp.javax.net.ssl.trustStoreType=Windows-ROOT
    

    使用此配置运行 Gradle 一次后,我不再需要 systemProp.javax.net.ssl.trustStore=NUL,直到我添加了另一个 maven 存储库。然后我又收到了PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

    Gradle 似乎在某处缓存了这个证书,因为在删除了我的用户主目录中的.gradle 目录后,我还需要再次使用systemProp.javax.net.ssl.trustStore=NUL。所以最好把它留在那里。

    【讨论】:

      【解决方案2】:

      Windows-ROOT 类型的密钥库应该可以工作 -- 它应该为当前用户访问存储的 TrustedRootCAs 部分(MMC/certmgr.msc 中的行,inetopt.cpl 中的选项卡)。在我的系统上,它是最大 UAC 的 8.1 Home,但不在域或工作组中并且没有策略更改(至少我没有授权),Java 代码能够插入到 Windows-ROOT 中——但它确实会弹出一个对话框关于“警告:即将安装 CA cert blah blah 这可能是安全风险 blah blah”,我必须单击它;如果该进程无法访问“工作站”(显示器),我不知道会发生什么,如果它失败也不会让我感到惊讶。用我的普通 id (local,admin) 和 Guest (local,peon) 确认;作为一个独立系统,我没有真正的计算机帐户,只有 IINM 实际上是 LocalSystem 的“本地计算机”,并且插入不会去那里。

      您可以尝试改用 Windows-MY,它应该并且对我来说确实可以(再次)为当前用户访问商店的个人部分;对我来说,在没有上述对话框的情况下工作。个人打算用于带有私钥的证书,可用于向服务器或收件人验证机器/用户,并在其中包含仅证书习惯于信任另一个系统可能会使您知识渊博的用户感到困惑甚至惊慌,但它确实对我有用。

      【讨论】:

      • 以防万一有人来这里寻找 Gradle 的解决方案(就像我一样),在项目根目录上创建一个名为 gradle.properties 的文件,其中包含 systemProp.javax.net.ssl.trustStoreType=Windows-ROOT 行。
      • 它与 Oracle JDK8 一起使用,但似乎不适用于 OpenJDK 11 :(
      • OpenJdk 11 中有代码可以做到这一点:github.com/AdoptOpenJDK/openjdk-jdk11/blob/master/src/…
      【解决方案3】:

      JSSE Reference Guide 回答您的问题。

      在这种情况下,如果存在这样的属性但它指定的文件确实存在 不,则不使用信任库。如果没有 javax.net.ssl.trustStore 属性存在,则搜索默认信任库。如果一个 找到名为 java-home/lib/security/jssecacerts 的信任库,它是 用过的。如果没有,则名为 java-home/lib/security/cacerts 的信任库 被搜索并使用(如果存在)。

      如果您没有权限覆盖这两个文件 jssecacerts 或 cacerts 之一,那么您的问题的答案是否定的。

      【讨论】:

        猜你喜欢
        • 2016-10-26
        • 1970-01-01
        • 1970-01-01
        • 2011-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-19
        • 2014-08-24
        相关资源
        最近更新 更多