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

问题描述 投票:122回答:8

我确实想将自签名证书导入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
java certificate ssl-certificate keystore keytool
8个回答
209
投票

在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

(可选)验证证书信息:

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

将证书导入Java cacerts密钥库:

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

编辑:

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


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

```


32
投票
    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"

13
投票

这对我有用。 :)

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

4
投票

如果您使用的是默认情况下未包含在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 -keystore -trustcacerts -file
  4. 如果要导入两个证书,则为每个证书指定的别名应该是唯一的。
  5. 在“密码”提示符下键入密钥库的密码,然后按Enter键。 cacerts文件的默认Java密码是“changeit”。在“信任此证书?”提示符下键入“y”,然后按Enter键。

1
投票

简单的命令'keytool'也适用于Windows和/或Cygwin。

如果你在这里使用Cygwin是我从“S.Botha's”答案的底部使用的修改过的命令:

  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"

请注意,因为如果这是在Cygwin下,你给了一个非Cygwin程序的路径,所以路径是类似DOS和引号。


0
投票

可能想试试

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

如果你只是写cacerts,我真的不知道它放在哪里你的证书只是给它一个完整的路径


0
投票

在java linux中安装证书

/ opt / jdk(version)/ bin / keytool -import -alias aliasname -file certificate.cer -keystore cacerts -storepass password

© www.soinside.com 2019 - 2024. All rights reserved.