我正在尝试在 Jenkins/Hudson 上配置我的电子邮件,但我不断收到错误消息:
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be
non-empty
我在网上看到了大量关于该错误的信息,但我还没有得到任何工作。我在 Fedora Linux(不是 OpenJDK)上使用 Sun 的 JDK。
这是我尝试过的几件事。我尝试遵循此 post 中的建议,但将 cacerts 从 Windows 复制到我的托管 Jenkins 的 Fedora 机器上没有用。我尝试关注 this guide,因为我试图将 Gmail 配置为我的 SMTP 服务器,但它也不起作用。我还尝试手动下载和移动这些 cacert 文件,然后使用 this guide 上的命令变体将它们移动到我的 Java 文件夹中。
我对任何建议持开放态度,因为我目前陷入困境。我已经让它在 Windows Hudson 服务器上工作,但我在 Linux 上苦苦挣扎。
这个奇怪的消息意味着您指定的 trustStore
是:
空的,
未找到,或
无法打开(例如,由于错误/缺少 trustStorePassword 或文件访问权限)。
(由于错误/缺少 trustStorePassword,或
文件访问权限,例如)。
另请参阅 @AdamPlumb 的 answer below。
在 Ubuntu 18.04 中,此错误有不同的原因(JEP 229,从 jks
密钥库默认格式切换到 pkcs12
格式,并且 Debian cacerts 文件生成使用默认新文件)和workaround:
# Ubuntu 18.04 and various Docker images such as openjdk:9-jdk throw exceptions when
# Java applications use SSL and HTTPS, because Java 9 changed a file format, if you
# create that file from scratch, like Debian / Ubuntu do.
#
# Before applying, run your application with the Java command line parameter
# java -Djavax.net.ssl.trustStorePassword=changeit ...
# to verify that this workaround is relevant to your particular issue.
#
# The parameter by itself can be used as a workaround, as well.
# 0. First make yourself root with 'sudo bash'.
# 1. Save an empty JKS file with the default 'changeit' password for Java cacerts.
# Use 'printf' instead of 'echo' for Dockerfile RUN compatibility.
/usr/bin/printf '\xfe\xed\xfe\xed\x00\x00\x00\x02\x00\x00\x00\x00\xe2\x68\x6e\x45\xfb\x43\xdf\xa4\xd9\x92\xdd\x41\xce\xb6\xb2\x1c\x63\x30\xd7\x92' > /etc/ssl/certs/java/cacerts
# 2. Re-add all the CA certs into the previously empty file.
/var/lib/dpkg/info/ca-certificates-java.postinst configure
状态 (2018-08-07),该错误已在 Ubuntu Bionic LTS 18.04.1 和 Ubuntu Cosmic 18.10 中修复。
🗹 Ubuntu 1770553: [SRU] backport ca-certificates-java from cosmic (20180413ubuntu1)
🗹 Ubuntu 1769013: Please merge ca-certificates-java 20180413 (main) from Debian unstable (main)
🗹 Ubuntu 1739631: Fresh install with JDK 9 can't use the generated PKCS12 cacerts keystore file
🗹 docker-library 145: 9-jdk image has SSL issues
🗹 JDK-8044445 : JEP 229: Create PKCS12 Keystores by Default
🖺 JEP 229: Create PKCS12 Keystores by Default
如果在此解决方法后问题仍然存在,您可能需要确保您实际运行的是刚刚修复的 Java 发行版。
$ which java
/usr/bin/java
您可以使用以下方法将 Java 替代设置为“自动”:
$ sudo update-java-alternatives -a
update-alternatives: error: no alternatives for mozilla-javaplugin.so
您可以仔细检查您正在执行的 Java 版本:
$ java --version
openjdk 10.0.1 2018-04-17
OpenJDK Runtime Environment (build 10.0.1+10-Ubuntu-3ubuntu1)
OpenJDK 64-Bit Server VM (build 10.0.1+10-Ubuntu-3ubuntu1, mixed mode)
还有其他替代解决方法,但这些都有其自身的副作用,需要额外的未来维护,而没有任何回报。
下一个最佳解决方法是添加行
javax.net.ssl.trustStorePassword=changeit
到文件
/etc/java-9-openjdk/management/management.properties
/etc/java-11-openjdk/management/management.properties
以存在者为准。
第三个问题最少的解决方法是更改
keystore.type=pkcs12
至
keystore.type=jks
在文件中
/etc/java-9-openjdk/security/java.security
/etc/java-11-openjdk/security/java.security
无论哪个存在,然后删除 cacerts
文件并按照帖子顶部解决方法脚本最后一行中描述的方式重新生成它。
这解决了我在 Ubuntu 上的问题:
sudo /var/lib/dpkg/info/ca-certificates-java.postinst configure
(在这里找到:https://bugs.launchpad.net/ubuntu/+source/ca-certificates-java/+bug/1396760)
ca-certificates-java
不是 Oracle JDK/JRE 中的依赖项,因此必须显式安装。
在 Ubuntu 18.04 上,根本原因是 openjdk-11-jdk(默认)和其他依赖它的包之间的冲突。它已经在 Debian 中修复,不久将包含在 Ubuntu 中。同时,最简单的解决方法是将您的 java 降级到版本 8。使用 ca-certificates-java
的其他解决方案要复杂得多。
首先删除冲突的包:
sudo apt-get remove --purge openjdk* java-common default-jdk
sudo apt-get autoremove --purge
通过以下方式检查您是否成功删除了所有相关包:
sudo update-alternatives --config java
系统将提示您没有可配置的 Java,否则此解决方法将失败。
然后重新安装所需的软件包:
sudo apt-get install openjdk-8-jdk
openjdk-8-jdk
包,删除 /etc/ssl/certs/java/cacerts
文件,然后运行 sudo update-ca-certificates -f
,这是从 pkcs12
格式的 cacerts 文件切换到 {5 } 格式化一个,如本线程其他地方所述。
EJP 基本上回答了这个问题(我意识到这有一个公认的答案),但我只是处理了这个边缘情况的问题,并希望让我的解决方案永垂不朽。
我之前设置为仅用于 SSL 访问的托管 Jira 服务器上出现 InvalidAlgorithmParameterException
错误。问题是我以 PKCS#12 格式设置了我的密钥库,但我的信任库是 JKS 格式。
在我的例子中,我编辑了我的 server.xml
文件以将 keystoreType 指定为 PKCS,但我没有指定 truststoreType,因此它默认为任何 keystoreType。明确指定 truststoreType 为 JKS 为我解决了这个问题。
-storetype jks
的方式并解决了它
我从博文 Fixing the trustAnchors problem when running OpenJDK 7 on OS X 中遇到了这个解决方案:
修复在 OS X 上运行 OpenJDK 7 时的 trustAnchors 问题。如果您在 OS X 上运行 OpenJDK 7 并看到此异常:
Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors
parameter must be non-empty
有一个简单的解决方法。只需链接到 Apple 的 JDK 1.6 使用的同一个 cacerts 文件:
cd $(/usr/libexec/java_home -v 1.7)/jre/lib/security
ln -fsh /System/Library/Java/Support/CoreDeploy.bundle/Contents/Home/lib/security/cacerts
您需要为已安装的每个 OpenJDK 版本执行此操作。只需将 -v 1.7
更改为您要修复的版本。运行 /usr/libexec/java_home -V
以查看您已安装的所有 JRE 和 JDK。
也许 OpenJDK 的人可以将它添加到他们的安装脚本中。
security
文件夹中的其他 3 个文件(blacklisted.certs
、local_policy.jar
和 US_export_policy.jar
)才能让 Java 满意。
jre
目录下的 cacerts
?
在 Ubuntu 12.10 (Quantal Quetzal) 或更高版本中,证书保存在 ca-certificates-java 包中。无论您使用的是什么 JDK,使用 -Djavax.net.ssl.trustStore=/etc/ssl/certs/java/cacerts
都会获取它们。
update-ca-certificates -f
来填充 cacerts 文件
在升级到 OS X v10.9 (Mavericks) 之后,我使用 JDK 1.7 在 OS X 上遇到了这个确切的问题。对我有用的解决方法是简单地重新安装 Apple 版本的 Java,可在 http://support.apple.com/kb/DL1572 获得。
我跑了
sudo update-ca-certificates -f
创建证书文件,然后:
sudo /var/lib/dpkg/info/ca-certificates-java.postinst configure
我又回来做生意了,谢谢大家。遗憾的是它没有包含在安装中,但我最终到达了那里。
sudo /var/lib/dpkg/info/ca-certificates-java.postinst configure**
我得到 sudo: /var/lib/dpkg/info/ca-certificates-java.postinst: command not found
ca-certificates-java
,在 Debian jessie 上使用来自 jessie-backports 的 openjdk-8-jre-headless
就足够了。我认为安装顺序很重要(ca-certificates-java
之后的 JRE 可能会导致这种情况,因为后者对向后移植的 Java 8 没有任何触发器)。
sudo /var/lib/dpkg/info/ca-certificates-java.postinst configure
无星 **
update-ca-certificates -f
是修复它的东西。我不需要第二个命令
该错误表明系统无法在参数 javax.net.ssl.trustStore
提供的路径中找到信任库。
在 Windows 下,我将 cacerts
文件从 jre/lib/security
复制到 Eclipse 安装目录(与 eclipse.ini
文件相同的位置)并在 eclipse.ini
中添加以下设置:
-Djavax.net.ssl.trustStore=cacerts
-Djavax.net.ssl.trustStorePassword=changeit
-Djavax.net.ssl.trustStoreType=JKS
我在 cacerts 的路径上遇到了一些问题(%java_home% 环境变量被某种方式覆盖了),所以我使用了这个简单的解决方案。
这个想法是提供信任库文件的有效路径 - 理想情况下,它会使用相对路径。您也可以使用绝对路径。
要确保存储类型是 JKS,您将运行以下命令:
keytool -list -keystore cacerts
Keystore type: JKS
Keystore provider: SUN
注意:由于证书有过期日期,或者可能由于其他原因失效,请不时检查 cacerts 中的证书是否仍然有效。您通常会在最新版本的 jdk 中找到证书的有效版本。
删除 ca-certificates-java 包并再次安装它对我有用 (Ubuntu MATE 17.10 (Artful Aardvark))。
sudo dpkg --purge --force-depends ca-certificates-java
sudo apt-get install ca-certificates-java
谢谢你,jdstrand:评论 1 错误 983302,回复:ca-certificates-java 无法在 Oneiric Ocelot 上安装 Java cacerts。
一些 OpenJDK 供应商版本是由于与二进制文件一起分发了一个空的 cacerts
文件而导致的。此处解释了该错误:https://github.com/AdoptOpenJDK/openjdk-build/issues/555
您可以将旧安装(如 c:\Program Files\Java\jdk1.8.0_192\jre\lib\security\cacerts
)中的文件复制到 adoptOpenJdk8\jre\lib\security\cacerts
。
AdoptOpenJDK 错误版本是 https://github.com/AdoptOpenJDK/openjdk8-releases/releases/download/jdk8u172-b11/OpenJDK8_x64_Win_jdk8u172-b11.zip
对我来说,这是由于信任库中缺少trustedCertEntry 造成的。
要测试,请使用:
keytool -list -keystore keystore.jks
它给了我:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
cert-alias, 31-Jul-2017, PrivateKeyEntry
即使我的 PrivateKeyEntry 包含一个 CA,它也需要单独导入:
keytool -import -alias root-ca1 -file rootca.crt -keystore keystore.jks
它导入证书,然后重新运行 keytool -list -keystore keystore.jks
现在给出:
Your keystore contains 2 entries
cert-alias, 31-Jul-2017, PrivateKeyEntry,
Certificate fingerprint (SHA1): <fingerprint>
root-ca1, 04-Aug-2017, trustedCertEntry,
Certificate fingerprint (SHA1): <fingerprint>
现在它有了一个trustedCertEntry,Tomcat就会成功启动。
升级到 OS X v10.9(小牛队)后,我遇到了很多安全问题:
亚马逊 AWS 的 SSL 问题
Peer 未通过 Maven 和 Eclipse 进行身份验证
trustAnchors 参数必须为非空
我应用了这个 Java 更新,它解决了我的所有问题:http://support.apple.com/kb/DL1572?viewlocale=en_US
我预计会出现这样的情况,因为我在 Talend Open Studio 中使用了备用 JVM(目前支持只存在到 JDK 1.7)。出于安全目的,我使用 8 ......无论如何
更新您的证书存储:sudo update-ca-certificates -f
然后
在初始化参数中添加一个新值 sudo gedit $(path to your architecture specific ini ie TOS_DI...ini) Djavax.net.ssl.trustStore=/etc/ssl/certs/java/cacerts
对我来说,第二个条目有效。我认为,根据 Talend Open Studio/TENt + JVM 的版本,它具有不同的参数名称,但它会查找相同的密钥库文件。
javax.net.ssl.trustAnchors
? JSSE 文档中没有提到它。
如果您在 Ubuntu 上使用 JDK9 和 Maven 遇到这种情况,您可以添加这个 JVM 选项 - 首先检查路径是否存在:
-Djavax.net.ssl.trustStore=/etc/ssl/certs/java/cacerts
如果文件丢失,请尝试安装 ca-certificates-java,如某人所述:
sudo apt install ca-certificates-java
我在 Linux 上的 Java 9.0.1 上收到此错误消息。这是由于 JDK 的一个已知错误,其中 .tar.gz 二进制包(从 http://jdk.java.net/9/ 下载)中的 cacerts 文件为空。
请参阅 JDK 9.0.1 Release Notes 的“已知问题”段落,说明“TLS 在 OpenJDK 9 上默认不起作用”。
在 Debian/Ubuntu(可能还有其他衍生产品)上,一个简单的解决方法是将 cacerts 文件替换为“ca-certificates-java”包中的文件:
sudo apt install ca-certificates-java
cp /etc/ssl/certs/java/cacerts /path/to/jdk-9.0.1/lib/security/cacerts
在 Red Hat Linux/CentOS 上,您可以从“ca-certificates”包中执行相同的操作:
sudo yum install ca-certificates
cp /etc/pki/java/cacerts /path/to/jdk-9.0.1/lib/security/cacerts
就我而言,客户端应用程序中使用的 JKS 文件已损坏。我创建了一个新的并在其中导入了目标服务器 SSL 证书。然后我在客户端应用程序中使用新的 JKS 文件作为信任库,例如:
System.setProperty("javax.net.ssl.trustStore",path_to_your_cacerts_file);
来源:Java SSL and certificate keystore
我使用(KeyStore Explorer)工具来创建新的 JKS。您可以从此链接下载它,KeyStore Explorer。
升级到 Spring Boot 1.4.1(或更高版本)后,您也可能会遇到此错误,因为它带来了 Tomcat 8.5.5 作为其依赖项的一部分。
问题在于 Tomcat 处理信任存储的方式。如果您碰巧在 Spring Boot 配置中指定了与您的密钥库相同的信任库位置,那么您可能会在启动应用程序时收到 trustAnchors parameter must be non-empty
消息。
server.ssl.key-store=classpath:server.jks
server.ssl.trust-store=classpath:server.jks
只需删除 server.ssl.trust-store
配置,除非您知道自己需要它,在这种情况下请参阅下面的链接。
以下问题包含有关该问题的更多详细信息:
HTTPS Tomcat 连接器无法从 1.4.1 #7069 启动
带有自签名证书的 SSL-client-auth 停止工作 #7406
升级到 Tomcat 8.5.5 #6703
我是可移植性的粉丝,所以我不安装 java,只需下载 tar.gz 并在路径中导出一些值,一切正常。
我解决了这个问题,但没有解决方案(安装或更新操作系统证书)对我有用。
我的错误是:我的jdk中的空cacerts。
我不知道为什么,但我的 jdk.tar.gz 有一个空的 cacerts 文件
/../some_openjdk/jre/lib/security/cacerts
大小:32 字节
下载自:
https://download.java.net/openjdk/jdk8u41/ri/openjdk-8u41-b04-linux-x64-14_jan_2020.tar.gz
https://download.java.net/java/GA/jdk9/9/binaries/openjdk-9_linux-x64_bin.tar.gz
使固定
经过几次尝试,我找到了一个正确的 jdk.tar.gz,其中包含一个大小为 101 KB 的 cacerts 文件
我从 https://github.com/AdoptOpenJDK/openjdk8-upstream-binaries 下载了这个打开的 jdk
https://github.com/AdoptOpenJDK/openjdk8-upstream-binaries/releases/download/jdk8u262-b10/OpenJDK8U-jdk-jfr_x64_linux_8u262b10.tar.gz
我在这个 Dockerfile 中找到了这个 url:
https://github.com/docker-library/openjdk/blob/b5d14d9165fad693901c285d6e7bbc36d1cde41f/8/jdk/Dockerfile
在从 Ubuntu 16.04 LTS (Xenial Xerus) 升级到 Ubuntu 18.04 LTS (Bionic Beaver) 后,我在尝试使用 Maven 3 时遇到了这个问题。
检查 /usr/lib/jvm/java-8-oracle/jre/lib/security 表明我的 cacerts 文件是指向 /etc/ssl/certs/java/cacerts
的符号链接。
我还有一个名为 cacerts.original
的可疑文件。
我将 cacerts.original
重命名为 cacerts
,从而解决了问题。
cacerts.original
文件采用 jks
格式,是使用 Ubuntu 16.04 的 Java 8 生成的,该格式使用该格式作为默认格式。 cacerts
文件采用 pkcs12
格式,由 Ubuntu 18.04 的 Java 10 生成,默认使用这种格式。正如本线程其他地方所解释的,新格式要求您将密码传递给可执行文件。但是,只要您生成一个新的空 jks
cacerts
文件或复制一个旧文件,下一个 cacerts 生成过程就会清空现有文件,并用文件系统中的 CA 证书重新填充它。
在更新 OS X v10.9 (Mavericks) 后,我在 OS X 上也遇到了这个问题,当时正在使用旧的 Java 6 并尝试访问 HTTPS URL。解决方法是 Peter Kriens 的逆。我需要将 1.7 空间中的 cacerts
复制到 1.6 版本链接的位置:
(as root)
umask 022
mkdir -p /System/Library/Java/Support/CoreDeploy.bundle/Contents/Home/lib/security
cp $(/usr/libexec/java_home -v 1.7)/jre/lib/security/cacerts \
/System/Library/Java/Support/CoreDeploy.bundle/Contents/Home/lib/security
我在使用 Android SDK sdkmanager 时遇到了这个问题。对我来说,这个解决方案有效:
转到 /usr/lib/jvm/java-8-oracle/jre/lib/security/ 将 cacert 替换为 cacert.original
cacert
文件很小 (22B)。我从 ppa:webupd8team/java
安装了 oracle-java8-installer
(根据本手册:https://docs.nativescript.org/start/ns-setup-linux)。
Marquis of Lorne's answer 是准确的,我添加了一些信息用于调试目的:
要调试此问题(我在 here 中写了更多详细信息)并了解正在使用(或尝试使用)的信任库,您可以添加 the property javax.net.debug=all 然后过滤有关信任库的日志.您还可以使用属性 javax.net.ssl.trustStore 来指定特定的信任库。例如 :
java -Djavax.net.debug=all -Djavax.net.ssl.trustStore=/Another/path/to/cacerts -jar test_get_https-0.0.1-SNAPSHOT-jar-with-dependencies.jar https://www.calca.com.py 2>&1| grep -i truststore
在 Red Hat Linux 上,我通过将证书导入 /etc/pki/java/cacerts
解决了这个问题。
System.setProperty("javax.net.ssl.trustStore", "C:\\Users\\user-id\\Desktop\\tomcat\\cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "passwd");
您必须将以上两行添加到您的代码中。它无法找到信任库。
java -Djavax.net.ssl.trustStore=/tmp/cacerts ...
,或者如果您想为使用 JDK 运行的所有程序全局设置它们,请将行添加到 JDK 的 management.properties
文件中。
郑重声明,没有这里的答案对我有用。我的 Gradle 构建开始因此错误神秘地失败,无法从 Maven central 获取特定 POM 文件的 HEAD。
事实证明,我已将 JAVA_HOME 设置为我自己的 OpenJDK 个人版本,这是我为调试 javac 问题而构建的。将其设置回我系统上安装的 JDK 修复了它。
在 Ubuntu 18.04 上,我需要使用 OpenJDK 1.7 来维护旧项目。我下载了二进制包。但是当我在上面执行我的脚本时,我得到了同样的错误。
解决方案是删除 jre/lib/security
文件夹中已下载 JDK 的 cacerts
文件,然后将其创建为 /etc/ssl/certs/java/
中系统 cacerts
文件的符号链接:
sudo ln -s /etc/ssl/certs/java/cacerts /path/to/downloaded/java/jre/lib/security/cacerts
这对任何人都有帮助,但是....对于任何从 Raspberry Pi 上的 Docker 映像(使用 AMD CPU)运行 Java 8 的人来说,我得到了以下 Dockerfile 来为我构建并成功运行
FROM hypriot/rpi-java
USER root
WORKDIR /usr/build/
RUN /usr/bin/printf '\xfe\xed\xfe\xed\x00\x00\x00\x02\x00\x00\x00\x00\xe2\x68\x6e\x45\xfb\x43\xdf\xa4\xd9\x92\xdd\x41\xce\xb6\xb2\x1c\x63\x30\xd7\x92' > /etc/ssl/certs/java/cacerts
RUN update-ca-certificates -f
RUN /var/lib/dpkg/info/ca-certificates-java.postinst configure
EXPOSE 8080
ARG JAR_FILE=target/app-0.0.1-SNAPSHOT.jar
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-Djavax.net.ssl.trustStorePassword=changeit", "-Djavax.net.ssl.trustStore=/etc/ssl/certs/java/cacerts", "-jar", "app.jar"]
我在运行特定的 Android 套件以在 Ubuntu 14.04 (Trusty Tahr) 上进行测试时遇到了这个问题。按照 shaheen 的建议,有两件事对我有用:
sudo update-ca-certificates -f
sudo /var/lib/dpkg/info/ca-certificates-java.postinst configure
不定期副业成功案例分享
${CATALINA_HOME}\conf
中有我的信任库,但没有设置CATALINA_HOME
,因此 Tomcat 在\conf
下寻找信任库。