You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置reactor.netty.http.client.HttpClient接受自签名证书

问题说明

使用reactor.netty.http.client.HttpClient请求走HTTPS协议、使用自签名证书的对外服务时,程序抛出SSL握手异常,核心报错栈如下:

Caused by: javax.net.ssl.SSLHandshakeException: General OpenSslEngine problem
        at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.handshakeException(ReferenceCountedOpenSslEngine.java:1895)
        at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.wrap(ReferenceCountedOpenSslEngine.java:822)
        at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:509)
        at io.netty.handler.ssl.SslHandler.wrap(SslHandler.java:1040)
        at io.netty.handler.ssl.SslHandler.wrapNonAppData(SslHandler.java:926)
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 sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
        at sun.security.validator.Validator.validate(Validator.java:260)
        at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
        at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:281)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
        ... 36 more

当前使用的HttpClient配置代码如下:

HttpClient client = HttpClient.create(connectionProvider);
if (isUseTLS) {
    Http11SslContextSpec http11SslContextSpec = Http11SslContextSpec.forClient();
    client = client.secure(spec -> {
                spec.sslContext(http11SslContextSpec);
    });
}

需求为不通过keytool导入证书到密钥库的方式,纯代码配置HttpClient使其接受自签名证书。

解决方案

可以通过编码自定义SSL信任规则实现,按使用场景分为两类:

  • 测试/非生产环境:配置信任所有证书(跳过证书校验),配置简单但存在安全风险,禁止用于生产环境
  • 生产环境:加载指定的自签名证书作为信任根,仅信任目标服务的自签名证书,兼顾便利性和安全性

方案1:测试环境跳过所有证书校验

配置SslContext时指定信任所有证书、关闭主机名校验,代码示例:

import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import reactor.netty.http.client.Http11SslContextSpec;

// ...
HttpClient client = HttpClient.create(connectionProvider);
if (isUseTLS) {
    Http11SslContextSpec http11SslContextSpec = Http11SslContextSpec.forClient();
    http11SslContextSpec.configure(sslContextBuilder -> {
        // 配置信任所有证书,不做证书链校验
        sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);
    });
    client = client.secure(spec -> {
        spec.sslContext(http11SslContextSpec)
            // 关闭主机名校验
            .handlerConfigurator(sslHandler -> sslHandler.setHostnameVerifier((hostname, session) -> true));
    });
}

注意:该方案会完全跳过SSL证书校验逻辑,存在中间人攻击风险,仅限本地开发、测试环境临时使用。

方案2:生产环境加载指定自签名证书

将自签名证书文件(一般为crt/pem格式)放在项目资源目录,代码加载该证书作为信任锚,仅信任该自签名证书,不需要修改JDK密钥库配置,证书随项目部署,适合容器化、多环境部署场景,代码示例:

import java.io.InputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import reactor.netty.http.client.Http11SslContextSpec;

// ...
HttpClient client = HttpClient.create(connectionProvider);
if (isUseTLS) {
    // 从资源目录加载目标服务的自签名证书
    try (InputStream certIs = getClass().getResourceAsStream("/your-self-signed-cert.crt")) {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate trustedCert = (X509Certificate) cf.generateCertificate(certIs);
        
        Http11SslContextSpec http11SslContextSpec = Http11SslContextSpec.forClient();
        http11SslContextSpec.configure(sslContextBuilder -> {
            // 仅信任加载的指定自签名证书
            sslContextBuilder.trustManager(trustedCert);
        });
        
        client = client.secure(spec -> spec.sslContext(http11SslContextSpec));
    } catch (Exception e) {
        throw new RuntimeException("加载自签名证书失败", e);
    }
}

内容的提问来源于stack exchange,提问作者wqliang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 07:54:33