如何正确地将自签名证书导入到默认情况下可用于所有 Java 应用程序的 Java 密钥存储库中?

我确实希望将一个自签名的证书导入到 Java 中,这样任何尝试建立 SSL 连接的 Java 应用程序都将信任这个证书。

目前为止,我设法把它导入了

keytool -import -trustcacerts -noprompt -storepass changeit -alias $REMHOST -file $REMHOST.pem
keytool -import -trustcacerts -noprompt -keystore cacerts -storepass changeit -alias $REMHOST -file $REMHOST.pem

尽管如此,当我尝试运行 HTTPSClient.class时,我仍然得到:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
482271 次浏览

在 Windows 上最简单的方法是使用程序 门环

  1. 下载并安装 portecle。
  2. 首先要100% 确定你知道哪个 JRE 或者 JDK 被用来运行你的程序。在64位的 Windows7上可能会有相当多的 JRE。进程资源管理器可以帮助您解决这个问题,或者您可以使用: System.out.println(System.getProperty("java.home"));
  3. 将文件 JAVA _ HOME lib security ccerts 复制到另一个文件夹。
  4. 在 Portecle 点击文件 > 打开密钥库文件
  5. 选择 ccerts 文件
  6. 输入此密码: changeit
  7. 单击“工具”> 导入可信证书
  8. 浏览文件 mycericate.pem
  9. 单击 Import
  10. 单击 OK 以获取有关信任路径的警告。
  11. 当它显示有关证书的详细信息时,单击 OK。
  12. 单击“是”接受证书为受信任证书。
  13. 当它请求别名时,单击 OK,当它说已导入证书时再次单击 OK。
  14. 单击“保存”。不要忘记这一点,否则更改将被丢弃。
  15. 把文件复制回原处。

在 Linux 上:

您可以从已经在使用 SSL 证书的 Web 服务器下载该证书,如下所示:

$ echo -n | openssl s_client -connect www.example.com:443 | \
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/examplecert.crt

可选地验证证书信息:

$ openssl x509 -in /tmp/examplecert.crt -text

将证书导入 Java ccerts 密钥存储库:

$ keytool -import -trustcacerts -keystore /opt/java/jre/lib/security/cacerts \
-storepass changeit -noprompt -alias mycert -file /tmp/examplecert.crt

最后,我编写了一个小脚本,将证书添加到密钥存储库中,这样使用起来就简单多了。

您可以从 https://github.com/ssbarnea/keytool-trust获得最新版本

#!/bin/bash
# version 1.0
# https://github.com/ssbarnea/keytool-trust
REMHOST=$1
REMPORT=${2:-443}


KEYSTORE_PASS=changeit
KEYTOOL="sudo keytool"


# /etc/java-6-sun/security/cacerts


for CACERTS in  /usr/lib/jvm/java-8-oracle/jre/lib/security/cacerts \
/usr/lib/jvm/java-7-oracle/jre/lib/security/cacerts \
"/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/cacerts" \
"/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/MacOS/itms/java/lib/security/cacerts"
do


if [ -e "$CACERTS" ]
then
echo --- Adding certs to $CACERTS


# FYI: the default keystore is located in ~/.keystore


if [ -z "$REMHOST" ]
then
echo "ERROR: Please specify the server name to import the certificatin from, eventually followed by the port number, if other than 443."
exit 1
fi


set -e


rm -f $REMHOST:$REMPORT.pem


if openssl s_client -connect $REMHOST:$REMPORT 1>/tmp/keytool_stdout 2>/tmp/output </dev/null
then
:
else
cat /tmp/keytool_stdout
cat /tmp/output
exit 1
fi


if sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' </tmp/keytool_stdout > /tmp/$REMHOST:$REMPORT.pem
then
:
else
echo "ERROR: Unable to extract the certificate from $REMHOST:$REMPORT ($?)"
cat /tmp/output
fi


if $KEYTOOL -list -storepass ${KEYSTORE_PASS} -alias $REMHOST:$REMPORT >/dev/null
then
echo "Key of $REMHOST already found, skipping it."
else
$KEYTOOL -import -trustcacerts -noprompt -storepass ${KEYSTORE_PASS} -alias $REMHOST:$REMPORT -file /tmp/$REMHOST:$REMPORT.pem
fi


if $KEYTOOL -list -storepass ${KEYSTORE_PASS} -alias $REMHOST:$REMPORT -keystore "$CACERTS" >/dev/null
then
echo "Key of $REMHOST already found in cacerts, skipping it."
else
$KEYTOOL -import -trustcacerts -noprompt -keystore "$CACERTS" -storepass ${KEYSTORE_PASS} -alias $REMHOST:$REMPORT -file /tmp/$REMHOST:$REMPORT.pem
fi


fi


done

```

    D:\Java\jdk1.5.0_10\bin\keytool -import -file "D:\Certificates\SDS services\Dev\dev-sdsservices-was8.infavig.com.cer" -keystore "D:\Java\jdk1.5.0_10\jre\lib\security\cacerts" -alias "sds certificate"

如果您使用的证书是由证书颁发机构签署的,默认情况下不包含在 Java ccerts 文件中,则需要为 HTTPS 连接完成以下配置。 将证书导入卡塞尔:

  1. 打开文件资源管理器并导航到 ccerts 文件,该文件位于安装了 AX Core Client 的 jre lib security 子文件夹中。默认位置是 C: Program Files ACL Software AX Core Client jre lib security

  2. 在进行任何更改之前创建文件的备份副本。

  3. 根据您正在使用的证书颁发机构颁发的证书,您可能需要将中间证书和/或根证书导入到 ccerts 文件中。使用以下语法导入证书:

    keytool -import -alias <alias> -keystore <cacerts_file> -trustcacerts -file <certificate_filename>

  4. 如果导入两个证书,则为每个证书指定的别名应该是唯一的。

  5. 在“ Password”提示符下键入密钥存储库的密码,然后按 Enter。Ccerts 文件的默认 Java 密码是“ changeit”。 在“信任此证书?”提示符下键入“ y”,然后按 Enter。

也许你该试试

keytool -import -trustcacerts -noprompt -keystore <full path to cacerts> -storepass changeit -alias $REMHOST -file $REMHOST.pem

我真的不知道它把你的证书如果你只是写 cacerts只是给它一个完整的路径

这招对我管用:)

sudo keytool -importcert -file filename.cer -alias randomaliasname -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit

简单的命令“ keytool”也可以在 Windows 和/或 Cygwin 上使用。

如果你正在使用 Cygwin ,这里是我在“ S.Botha”下面使用的修改后的命令:

  1. 确保在 JDK 中标识您将要使用的 JRE
  2. 启动您的提示/cygwin 作为管理员
  3. 进入该 JDK 的 bin 目录,例如 cd/cygdrive/c/Program Files/Java/jdk1.8.0 _ 121/jre/bin
  4. 从内部执行 keytool 命令,在最后提供新 Cert 的路径,如下所示:

    ./keytool.exe -import -trustcacerts -keystore ../lib/security/cacerts  -storepass changeit -noprompt -alias myownaliasformysystem -file "D:\Stuff\saved-certs\ca.cert"
    

Notice, because if this is under Cygwin you're giving a path to a non-Cygwin program, so the path is DOS-like and in quotes.

在 java linux 中安装证书

/opt/jdk (version)/bin/keytool-import-aliasname-file 證 icate.cer-keystore ccerts-storepass password

首先从提供程序获取证书。创建一个以. cer 结尾的文件并粘贴证书。

复制文本文件或将其粘贴到您可以访问的地方,然后使用 cmd 提示符作为管理员并将 cd 文件粘贴到 jdk 的 bin; 将使用的命令是: keytool

用以下方法更改密钥存储库的密码:

keytool -storepasswd -keystore "path of the key store from c\ and down"

密码是: changeit

然后,系统会要求您输入新密码两次,然后键入以下内容:

keytool -importcert -file "C:\Program Files\Java\jdk-13.0.2\lib\security\certificateFile.cer" -alias chooseAname -keystore  "C:\Program Files\Java\jdk-13.0.2\lib\security\cacerts"

您可以在应该位于 $JAVA_HOME/bin中的 Java 安装中使用 keytool。Java 密钥存储库位于 $JAVA_HOME/lib/security/cacerts$JAVA_HOME/jre/lib/security/cacerts中,这取决于您是否安装了 JDK 或 JRE。

如果使用 Java9或更高版本,则不需要知道确切的位置。您可以使用 -cacerts选项作为快捷方式。

Java9 +

因此,对于 Java9(又名 Java1.9)或更高版本,只需使用

keytool -importcert -trustcacerts -cacerts -file myCert.pem -alias myCert

早期的 Java 版本

对于 Java8(也就是1.8)或更早的版本,您必须像这样指定密钥存储库位置

keytool -importcert -trustcacerts -keystore $JAVA_HOME/lib/security/cacerts -file myCert.pem -alias myCert

对于 Java5(也就是1.5)或更早的版本,-importcert选项不存在。它被称为 -import,但除此之外,它是完全相同的。那就用吧

keytool -import -trustcacerts -keystore $JAVA_HOME/lib/security/cacerts -file myCert.pem -alias myCert

其他选择

  • 您将被要求输入信任库密码,默认密码是 改变
  • 如果需要在无人参与的情况下运行导入,可以添加 -storepass changeit -noprompt

格式

keytool可以导入 X.509 v1、 v2和 v3证书,以及 PKCS # 7格式化的证书链,这些证书链由该类型的证书(P7B)组成。必须提供要导入的数据

  • 二进制编码格式(DER)
  • 或者以可打印的编码格式(即 base64编码) ,封装在 -----BEGIN-----END行(PEM)中

注意: 我不确定 PEM 格式的证书链是否真的有效。

额外的剧本

恐怕,这是 bash,所以对 Windows 用户没有解决方案。

这个简单的脚本创建于 stackoverflow 中的几个有用问题和智能答案,它检查 Java 版本,并且(如果需要的话)确定正确的密钥存储位置,它可以在一个命令中导入多个证书。注意,必须用单引号传递文件模式参数(参见使用方法)。

#!/bin/bash


# Add custom root certificates to Java trust store


if [ "$#" -ne 1 ]; then
SCRIPT=`basename "$0"`
echo "Usage: $SCRIPT 'path/to/certs/*'"
exit 1
fi


CERTFILES=$1


JAVA_VERSION=`java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1`


if (( $JAVA_VERSION >= 9 )); then
CACERTS="-cacerts"
else
# Check where cacerts are located
# differs depending or jdk or jre installed
if [ -d "$JAVA_HOME/jre" ]; then
CACERTS="$JAVA_HOME/jre"
else
CACERTS="$JAVA_HOME"
fi
CACERTS="-keystore $CACERTS/lib/security/cacerts"
fi


# Now add certificates
for CERTFILE in $CERTFILES; do
# Remove path, then suffix to derive alias from filename
ALIAS=${CERTFILE##*/}
ALIAS=${ALIAS%.*}
$JAVA_HOME/bin/keytool -importcert -file "$CERTFILE" -alias "$ALIAS" $CACERTS -trustcacerts -storepass changeit -noprompt
if [ $? -ne 0 ]; then
echo "Failed to add $CERTFILE as $ALIAS to $CACERTS"
exit 1
fi
done

在 Windows 中,这些命令在命令行上工作:

cd C:\Program Files\Java\jre1.8.0_301\lib\security\
keytool -import -trustcacerts -alias cert_ssl -file C:\opt\esb-config\keystores\cert.cer -noprompt -storepass changeit -keystore cacerts

changeit是信任存储区的默认密码。