自签名以外的所有证书均由 CA 软件签名;也许您的意思是由您自己或由公共“知名”CA 以外的某个实体(可能是雇主或其他当地组织)运营的 CA 软件。这几乎是您需要将 CA 根证书显式添加到您的(客户端)信任库的唯一情况,因为(大多数)知名 CA 的根在大多数情况下都已预先安装,尤其是在 Windows 和 Java 中。
此类“私有”CA可以像知名 CA 一样使用中间(链)证书,但通常不会。
最简单、最准确的方法是只做一个虚拟请求:
new URL ("https://hostname:port/pathifneeded") .openConnection() .connect();
这将根据“当前”本地信任库和请求的主机名验证收到的证书链(如果直接从根颁发,则可能只是证书,见上文)作为所有客户端/请求应该做。这包括正确的链接,包括扩展和约束、签名有效、未过期(或将来),以及如果证书和您的 JVM 都(全部)为 OCSP 配置的撤销。
如果有任何错误,它会抛出异常。对于一个简单的独立测试程序,您不需要编写任何异常处理,只需使用 JVM 默认打印出未捕获的异常即可。对于更复杂的环境,您可能希望捕获异常并做一些不同的事情。
默认使用的信任库是Java 默认信任库,它是JRE/lib/security 目录中cacerts(或jssecacerts,如果存在)的内容。对于 Sun/Oracle Java 程序包,此文件由程序包提供,最初包含 Sun/Oracle 批准的 CA 根。对于 Unix 上的 OpenJDK 包,有时它会链接到专门提供根证书的不同包,例如在 CentOS(我使用)上,ca-certificates 包在(大部分)/etc/pki 中。请注意,您可以在一个系统上安装多个 JRE;如果是这样,请确保您设置并使用正确的。
在 Windows(仅限)上,您可以使用 Windows 证书存储区,方法是在命令行中使用 -D 或调用 System.setProperty 指定 sysprop javax.net.ssl.trustStoreType 值 Windows-ROOT 之前在https URL 上使用.openConnection(),或对默认SSL 套接字工厂的任何其他使用。
如果您不想检查主机名,可以通过将HttpsURLConnection 临时放在变量中并调用类似的东西来覆盖默认主机名验证器
httpsconn.setHostNameVerifier( new HostnameVerifier() {
boolean verify (String name, SSLSession session){ return true; }
} );
在执行.connect() 之前或通过调用类似的方法
HttpsURLConnection.setDefaultHostnameVerifier( ...as above... );
在.openConnection() 之前。