Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
`生成自己的SSLContext(Java)时找不到有效的证书路径…`_Java_Ssl_Certificate - Fatal编程技术网

`生成自己的SSLContext(Java)时找不到有效的证书路径…`

`生成自己的SSLContext(Java)时找不到有效的证书路径…`,java,ssl,certificate,Java,Ssl,Certificate,我试图在运行时通过SSLContext对象向HttpClient添加一个证书,这样我就可以将程序分发给任何拥有JVM的人,而他们不必担心通过keytool实用程序加载证书。证书本身将与程序打包为资源 尽管我将分享的关于错误消息的许多其他答案在历史上都是通过使用keytool来回答的,但我真的不希望我的最终用户被它拖累。关于StackOverflow有一小部分问题,它们越过了keytool,试图提供一个替代解决方案,但这是我发现的最接近我实际困境的问题 它与我的场景完全匹配,但随后导入一个现有的信

我试图在运行时通过SSLContext对象向HttpClient添加一个证书,这样我就可以将程序分发给任何拥有JVM的人,而他们不必担心通过
keytool
实用程序加载证书。证书本身将与程序打包为资源

尽管我将分享的关于错误消息的许多其他答案在历史上都是通过使用
keytool
来回答的,但我真的不希望我的最终用户被它拖累。关于StackOverflow有一小部分问题,它们越过了keytool,试图提供一个替代解决方案,但这是我发现的最接近我实际困境的问题

它与我的场景完全匹配,但随后导入一个现有的信任库,而不是在运行时创建一个信任库并用证书加载它

我的问题是:当我有运行时密钥库对象可供使用时,我甚至需要保存一个文本密钥库吗?如果是这样,为什么我的代码不起作用

以下是我的代码框架(请原谅任何违反规范的行为,我对Java编码还不熟悉):

下面是它抛出的错误(这与证书根本没有作为上下文添加的情况相同):


我在挠头。有人知道我能做什么吗?

错误消息没有说明密钥库的质量-它只是说明无法匹配合适的证书来验证服务器提供的证书

当我解决了同样的问题时,我在编译时构建了一个密钥库文件,然后将其作为资源添加到应用程序jar中。应用程序通过从资源流加载来创建keystore对象——从那里我们的代码看起来非常相似


因此,我将更多地关注密钥库中的证书以及服务器呈现的内容。至少在我的环境中,我发现了一些复活节彩蛋(例如,提交给我的开发机器的证书与其他用户或以后的生产中的证书不同)。

我不建议将代码分解为无数这样的单行例程(方法),这会使阅读变得非常困难。但是如果(1)从
buildClient()
返回用于连接,并且(2)您加载的证书是您连接到的站点的正确锚,那么它应该可以工作,并且对我来说是“明显”完成的。您可以使用sysprop
javax.net.debug=ssl:handshake:trustmanager
(并捕获输出)运行,以查看服务器正在发送的证书链,并查看它与您的锚的比较情况。结合我标记为正确答案的响应,此系统属性帮助我查看加载了错误的证书。谢谢你的建议!非常感谢。经过仔细检查,我发现我有一个非常相似但不正确的证书。集中调试证书本身使我到达了终点。
private HttpClient buildClient() {
    return HttpClient.newBuilder()
            .version(HttpClient.Version.HTTP_1_1)
            .followRedirects(HttpClient.Redirect.ALWAYS)
            .sslContext(getSSLContext())  // Where I set the SSLContext
            .cookieHandler(new CookieManager(null, CookiePolicy.ACCEPT_ALL))
            .connectTimeout(Duration.ofMinutes(2L))
            .build();
}

private SSLContext getSSLContext() {
    try {
        return createSSLContext();
    } catch (Exception e) {
        throw new RuntimeException("The necessary certificate could not be added to the HttpClient");
    }
}

private SSLContext createSSLContext() throws NoSuchAlgorithmException, CertificateException, KeyStoreException, KeyManagementException, IOException {
    SSLContext context = SSLContext.getInstance("SSLv3");
    TrustManager[] trustManagers = createTrustManagers();
    context.init(null, trustManagers, null);
    return context;
}

private TrustManager[] createTrustManagers() throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
        TrustManagerFactory factory = TrustManagerFactory.getInstance("PKIX");
    factory.init(getConfiguredKeyStore());
    return factory.getTrustManagers();
}

private KeyStore getConfiguredKeyStore() throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException {
        Certificate certificate = getCertificate();
    KeyStore keyStore = createNewKeystore();
    keyStore.setCertificateEntry("www.thewebsite.com", certificate);
    return keyStore;
}

private KeyStore createNewKeystore() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    char[] password = "password".toCharArray();
    keyStore.load(null, password);
    return keyStore;
}

private Certificate getCertificate() throws CertificateException {
    InputStream certStream = getClass().getClassLoader().getResourceAsStream("certFile.crt");
    CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
    return certFactory.generateCertificate(certStream);
}
Exception in thread "main" javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:556)
    at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:119)
    at CustomHttpClient.authenticate(CustomHttpClient.java:41)
    at Main.main(Main.java:61)
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:369)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:312)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:307)
    at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:654)
    at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:473)
    at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:369)
    at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
    at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:480)
    at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1267)
    at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1254)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:691)
    at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1199)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.lambda$executeTasks$3(SSLFlowDelegate.java:1122)
    at java.net.http/jdk.internal.net.http.HttpClientImpl$DelegatingExecutor.execute(HttpClientImpl.java:155)
    at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.executeTasks(SSLFlowDelegate.java:1117)
    at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.doHandshake(SSLFlowDelegate.java:1083)
    at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:484)
    at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:268)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$TryEndDeferredCompleter.complete(SequentialScheduler.java:315)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
    at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439)
    at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
    at java.base/sun.security.validator.Validator.validate(Validator.java:264)
    at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:285)
    at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:144)
    at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:632)
    ... 23 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
    at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
    at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
    at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434)
    ... 28 more