如何将自签名证书正确导入Java密钥库,默认情况下可供所有Java应用程序使用?

sor*_*rin 133 java certificate keystore keytool ssl-certificate

我确实想将自签名证书导入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
Run Code Online (Sandbox Code Playgroud)

不过,当我尝试跑步时,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

Sar*_*tha 215

在Windows上,最简单的方法是使用程序portecle.

  1. 下载并安装portecle.
  2. 首先100%确定您知道正在使用哪个JRE或JDK来运行您的程序.在64位Windows 7上可能会有相当多的JRE.Process Explorer可以帮助您,或者您可以使用:System.out.println(System.getProperty("java.home"));
  3. 将文件JAVA_HOME\lib\security\cacerts复制到另一个文件夹.
  4. 在Portecle中,单击"文件">"打开密钥库文件"
  5. 选择cacerts文件
  6. 输入以下密码:changeit
  7. 单击工具>导入可信证书
  8. 浏览文件mycertificate.pem
  9. 单击导入
  10. 单击"确定"以获取有关信任路径的警告.
  11. 显示证书详细信息时,单击"确定".
  12. 单击是以接受证书为受信任.
  13. 当它要求别名时单击"确定",并在它说已导入证书时再次单击"确定".
  14. 点击保存.不要忘记这一点或更改被丢弃.
  15. 将文件cacerts复制回您找到它的位置.

在Linux上:

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

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

(可选)验证证书信息:

$ openssl x509 -in /tmp/examplecert.crt -text
Run Code Online (Sandbox Code Playgroud)

将证书导入Java cacerts密钥库:

$ keytool -import -trustcacerts -keystore /opt/java/jre/lib/security/cacerts \
   -storepass changeit -noprompt -alias mycert -file /tmp/examplecert.crt
Run Code Online (Sandbox Code Playgroud)

编辑:

这些天我们不必经常向密钥库添加证书,因为您可以从ssls.com获得每年5美元的证书.以防万一这是你的选择.

  • 我没有使用过portecle,但我发现[Keystore Explorer](http://keystore-explorer.sourceforge.net/)适用于Windows,Linux,(它也适用于OSX) (6认同)
  • 在2019年,我们甚至可以使用Lets加密等服务免费获得SSL证书 (4认同)
  • 其主要思想不是 portecle,而是将证书导入正确的密钥库。 (3认同)
  • 仅供参考,按照 Linux 的步骤在 MacOS 上也能正常工作 (2认同)

Vik*_*kky 38

    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"
Run Code Online (Sandbox Code Playgroud)

  • 系统将提示您输入密钥库密码,默认为"changeit" (12认同)
  • 至少在 java 11 (sapmachine jre) 中,语法根据 manfile 略有变化:`keytool.exe -importcert -file <path to cer file> -cacerts -alias "<your alias>"` (2认同)

sor*_*rin 32

我最终编写了一个将证书添加到密钥库的小脚本,因此使用起来更加容易.

您可以从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
Run Code Online (Sandbox Code Playgroud)

```

  • “sudo keytool”不 (3认同)

not*_*vvy 24

您可以与 Java 安装一起使用keytool,该安装应位于$JAVA_HOME/bin. Java 密钥库位于$JAVA_HOME/lib/security/cacerts$JAVA_HOME/jre/lib/security/cacerts取决于您是否安装了 JDK 或 JRE。

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

Java 9+

因此,对于 Java 9(又名 Java 1.9)或更高版本,只需使用

keytool -importcert -trustcacerts -cacerts -file myCert.pem -alias myCert
Run Code Online (Sandbox Code Playgroud)

早期的 Java 版本

对于 Java 8(又名 1.8)或更早版本,您必须像这样指定密钥库位置

keytool -importcert -trustcacerts -keystore $JAVA_HOME/lib/security/cacerts -file myCert.pem -alias myCert
Run Code Online (Sandbox Code Playgroud)

对于 Java 5(又名 1.5)或更早版本,该-importcert选项不存在。它被称为-import,但除此之外它是相同的。所以使用

keytool -import -trustcacerts -keystore $JAVA_HOME/lib/security/cacerts -file myCert.pem -alias myCert
Run Code Online (Sandbox Code Playgroud)

其他选项

  • 系统会要求您输入信任库密码,默认密码是Changeit
  • 如果您需要在无人值守的情况下运行导入,您可以添加-storepass changeit -noprompt

格式

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

  • 二进制编码格式 (DER)
  • 或采用可打印编码格式(又名 base64 编码),包含在-----BEGIN-----END行中 (PEM)

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

奖励脚本

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

这个简单的脚本是根据 stackoverflow 上的几个有用的问题和聪明的答案创建的,它检查 Java 版本,并在必要时确定正确的密钥库位置,并且它可以在一个命令中导入多个证书。请注意,您必须用单引号传递文件模式参数(请参阅用法)。

添加证书.sh

#!/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
Run Code Online (Sandbox Code Playgroud)


Wal*_*alk 16

这对我有用.:)

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

  • 请注意,您可以使用“-cacerts”选项,而不是使用“-keystore”提供路径。这很有用,因为确切的路径取决于您是否安装了 jdk 或 jre。 (4认同)

Bha*_*akh 5

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

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

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

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

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

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

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