将 JRE 设置为使用 Windows 信任存储区,特别是用户的信任存储区



摘要: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 信任存储区,而不仅仅是计算机帐户的存储区?

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

您可以尝试Windows-MY,它应该并且对我来说确实为(再次)当前用户访问商店的个人部分; 对我来说,无需上述对话框即可工作。个人用于带有私钥的证书,可用于向服务器或收件人验证机器/用户,并且在其中仅使用证书来信任另一个系统可能会混淆甚至警告您知识渊博的用户,但它确实对我有用。

除了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。所以最好把它留在那里。

JSSE 参考指南回答了您的问题。

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

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

最新更新