我正在设置与我无法控制的远程服务器的HTTPS连接。服务器具有SSL证书,该证书由受信任的CA生成,但在SSL握手中不包含中间证书。
EG。 可信CA证书 - >中级证书(未提供) - >服务器证书(已提供)
通常,服务器将提供服务器证书和中间证书。如果没有中间证书,我的HTTP客户端将无法识别SSL证书,并且SSL连接将失败。
我正在尝试使用Apache HTTP客户端4.5进行连接:
val httpClientBuilder = HttpClientBuilder.create()
.useSystemProperties()
如果我下载证书,将它们设置在密钥库中并将其附加到连接上,我就能解决问题:
Security.addProvider(new BouncyCastleProvider())
val certPem = new PEMParser(new PemReader(new FileReader("trust-chain.crt")))
val certHolder = certPem.readObject().asInstanceOf[X509CertificateHolder]
val cert = new JcaX509CertificateConverter()
.setProvider("BC")
.getCertificate(certHolder)
val keyStore = KeyStore.getInstance(KeyStore.getDefaultType)
keyStore.load(null)
keyStore.setCertificateEntry("cert-alias", cert)
val sslContextBuilder = SSLContextBuilder.create()
.loadKeyMaterial(keyStore, "changeit".toCharArray)
.loadTrustMaterial(keyStore, null)
val httpClientBuilder = HttpClientBuilder.create()
.useSystemProperties()
.setSSLContext(sslContextBuilder.build())
但是一旦证书过期,这就会破裂。我还可以启用信任自签名证书,但这有很大的安全隐患,我不想那样:
val sslContextBuilder = SSLContextBuilder.create()
.loadKeyMaterial(keyStore, "changeit".toCharArray)
.loadTrustMaterial(keyStore, new TrustSelfSignedStrategy)
有没有办法设置Apache HTTP Client(或其他JVM HTTPS / SSL库),以便在服务器不提供中间证书时自动下载中间证书(类似于大多数Web浏览器)?
答案 0 :(得分:0)
我找到了an answer。
使用Oracle JRE,您可以使用Java系统属性-Dcom.sun.security.enableAIAcaIssuers=true
来自动下载中间证书
要使其正常工作,服务器的证书必须提供URI给中间证书(证书的颁发者)。