找不到请求的目标的有效证书路径 - 签名证书



我正在研究一个代码,该代码通过代理连接到 Slack,该代理充当 MITM 并用自己的自签名证书替换 slack 证书。我将代理的证书添加到信任存储中,并将我的 RestTemplate 配置为使用信任存储:

def sslContext = new SslContextBuilder().withTrustStore(trustStoreResource, trustStorePassword).build()
def proxy = proxyEnabled ? new HttpHost(proxyHost, proxyPort) : null
def httpClient = HttpClients.custom().setProxy(proxy).setSSLContext(sslContext).build()
def result = new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient))

这工作正常。但是,在我的本地,我不通过代理直接连接到松弛。换句话说,上述代码中的httpClient将使用SSLContext而不是代理进行配置。我本来以为这很好,因为 Slack 的证书是使用有效的根 CA 签名的,但我的代码无法验证 Slack 的证书。

我假设这是因为我的 trustore,但我对为什么会发生这种情况感到困惑。发生这种情况是因为根 CA 未导入我的信任吗?如果是这样,我将如何在不必维护根 CA 的情况下执行此操作?

我知道在本地我可以避免设置信任存储,但如果可能的话,我想避免在代码中添加分支。

我最终做的是使用 https://gist.github.com/JensRantil/9b7fecb3647ecf1e3076 中的实现将系统的默认信任存储与我的信任存储组合在一起,然后使用以下类来构建我的 SSL 上下文。很遗憾HttpClient不提供这个,但可能有一个很好的理由。

import org.springframework.core.io.Resource
import javax.net.ssl.KeyManager
import javax.net.ssl.KeyManagerFactory
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import java.security.KeyStore
class SslContextBuilder {
private KeyManager[] keyManagers = []
private TrustManager[] trustManagers = []
SslContextBuilder withKeyStore(Resource resource, String password) {
def keyStore = KeyStore.getInstance('JKS')
keyStore.load(resource.getInputStream(), password.chars)
KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
kmfactory.init(keyStore, password.chars)
KeyManager[] kms = kmfactory.getKeyManagers()
keyManagers += kms ? kms : []
this
}
SslContextBuilder withTrustStore(Resource resource, String password) {
def trustStore = KeyStore.getInstance('JKS')
trustStore.load(resource.getInputStream(), password.chars)
def tss = CompositeX509TrustManager.getTrustManagers(trustStore)
trustManagers += tss ? tss : []
this
}
SSLContext build() {
def sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, null)
sslContext
}
}

相关内容