问题
我确实想将自签名证书导入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
#1 热门回答(166 赞)
在Windows上,最简单的方法是使用程序portecle。
- 下载并安装portecle。
- 首先100%确定你知道正在使用哪个JRE或JDK来运行你的程序。在64位Windows 7上可能会有相当多的JRE。 Process Explorer可以帮助你,或者你可以使用:System.out.println(System.getProperty("java.home"));
- 将文件JAVA_HOME \ lib \ security \ cacerts复制到另一个文件夹。
- 在Portecle中,单击"文件">"打开密钥库文件"
- 选择cacerts文件
- 输入此密码:changeit
- 单击工具>导入可信证书
- 浏览文件mycertificate.pem
- 单击"导入"
- 单击"确定"以获取有关信任路径的警告。
- 显示有关证书的详细信息时,单击"确定"。
- 单击"是"将证书接受为受信任。
- 当它要求别名时单击"确定",并在说明已导入证书时再次单击"确定"。
- 单击"保存"。不要忘记这一点或更改被丢弃。
- 将文件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美元的证书。以防这是你的选择。
#2 热门回答(27 赞)
我最终编写了一个将证书添加到密钥库的小脚本,因此使用起来更加容易。
你可以从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
----
## #3 热门回答(23 赞)
```java
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"