使用http客户端 - 如何让Java自动下载中间SSL证书

时间:2016-11-15 02:07:46

标签: java scala https

我正在设置与我无法控制的远程服务器的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浏览器)?

1 个答案:

答案 0 :(得分:0)

我找到了an answer

使用Oracle JRE,您可以使用Java系统属性-Dcom.sun.security.enableAIAcaIssuers=true来自动下载中间证书

要使其正常工作,服务器的证书必须提供URI给中间证书(证书的颁发者)。