假设我正在通过https与客户端通信,并使用此证书链:
acme root
|
+--- acme intermediate
|
+--- server cert
我已经创建了一个信任存储库,我使用
导入了acme intermediate
证书
keytool -import -alias intermediate-ca -file acme_intermediate.der -keystore /path/to/intermediate-cacerts
并用...
启动虚拟机java -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStore=/path/to/intermediate-cacerts ...
连接到服务器时,连接成功。由于javax.net.ssl.SSLHandshakeException
证书未存储在我的unable to find valid certification path to requested target
中,我预计会acme root
与intermediate-ca
或类似{/ 1}}。
可以肯定的是,我已经检查了JVM是否通过strace
JVM检查了默认的系统信任库,但它没有:
$ strace -tt -f -etrace=open java -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStore=/path/to/intermediate-cacerts Program 2>&1 | grep -vE 'open\((.*\.(so|jar)|"/(proc|dev|etc/host|tmp|sys))'
22:31:21.103201 open("/usr/lib/jvm/java-1.7.0-oracle-1.7.0.51.x86_64/jre/lib/amd64/jvm.cfg", O_RDONLY) = 3
[pid 27619] 22:31:21.119299 open("/usr/lib/jvm/java-1.7.0-oracle-1.7.0.51.x86_64/jre/lib/endorsed", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
[pid 27619] 22:31:21.125422 open("/etc/nsswitch.conf", O_RDONLY) = 3
[pid 27619] 22:31:21.127423 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
[pid 27619] 22:31:21.141141 open("/usr/lib/jvm/java-1.7.0-oracle-1.7.0.51.x86_64/jre/lib/meta-index", O_RDONLY) = 3
[pid 27619] 22:31:21.540826 open("/usr/lib/locale/locale-archive", O_RDONLY) = 4
[pid 27619] 22:31:21.541576 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 4
[pid 27619] 22:31:21.542221 open("/etc/localtime", O_RDONLY) = 4
[pid 27619] 22:31:22.267438 open("/usr/lib/jvm/java-1.7.0-oracle-1.7.0.51.x86_64/jre/lib/ext/meta-index", O_RDONLY) = 4
[pid 27619] 22:31:22.318007 open("/usr/lib/jvm/java-1.7.0-oracle-1.7.0.51.x86_64/jre/lib/ext", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
[pid 27619] 22:31:22.462944 open("/usr/java/packages/lib/ext", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid 27619] 22:31:22.604155 open("/home/me/Program.class", O_RDONLY) = 4
[pid 27619] 22:31:22.728273 open("/usr/lib/jvm/java-1.7.0-oracle-1.7.0.51.x86_64/jre/lib/security/java.security", O_RDONLY) = 4
[pid 27619] 22:31:24.048924 open("/usr/share/jbossas/standalone/data/intermediate-cacerts", O_RDONLY) = 9
[pid 27619] 22:31:24.462164 open("/usr/lib/jvm/java-1.7.0-oracle-1.7.0.51.x86_64/jre/lib/meta-index", O_RDONLY) = 10
[pid 27619] 22:31:24.626192 open("/etc/resolv.conf", O_RDONLY) = 11
[pid 27619] 22:31:25.523615 open("/usr/lib/jvm/java-1.7.0-oracle-1.7.0.51.x86_64/jre/lib/net.properties", O_RDONLY) = 12
[pid 27619] 22:31:26.168961 --- SIGSEGV (Segmentation fault) @ 0 (0) ---
Successfully connected
省略-Djavax.net.ssl
选项时,我会观察系统信任库的open()
:
[pid 27212] 10:54:53.699479 open("/usr/lib/jvm/java-1.7.0-oracle-1.7.0.51.x86_64/jre/lib/security/cacerts", O_RDONLY) = 9
使用此代码片段创建连接:
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(hostname, port);
互联网上的这几项资源表明,无法在多个信任库中制作Java查找证书。他们说需要克隆系统信任库并导入所需的额外证书。听起来似乎有道理。