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

解决WireMock自签名SSL的javax.net.ssl.SSLHandshakeException错误

解决WireMock自签SSL证书主机名不匹配问题

核心原因

WireMock默认生成的自签证书CN为Tom Akehurst,而Java的SSL握手会严格校验请求主机名(localhost)与证书中的CN/SAN(Subject Alternative Name)是否一致,因此即使证书已导入信任库,仍会抛出javax.net.ssl.SSLHandshakeException: No name matching localhost found错误。Chrome/Postman因校验策略宽松可正常访问,但Java客户端不会忽略该不匹配。


解决方案1:生成自定义自签证书(推荐)

生成包含localhost作为CN和SAN的自签证书,替换WireMock默认证书:

步骤1:生成自定义keystore

使用JDK自带的keytool生成符合要求的证书:

keytool -genkeypair -alias wiremock-localhost -keyalg RSA -keysize 2048 -validity 3650 -keystore wiremock-localhost.jks -dname "CN=localhost, OU=Dev, O=Local, L=City, ST=State, C=CN" -ext SAN=DNS:localhost,DNS:127.0.0.1 -storepass password -keypass password
  • -ext SAN=DNS:localhost,DNS:127.0.0.1:添加SAN扩展,同时支持localhost和127.0.0.1两种访问方式
  • storepass和keypass可自定义,需记住后续配置使用

步骤2:导入证书到信任库

将生成的证书导入Java信任库(推荐使用自定义信任库,避免修改系统文件):

# 生成自定义信任库
keytool -importkeystore -srckeystore wiremock-localhost.jks -destkeystore truststore.jks -srcstorepass password -deststorepass password

# 若需导入系统默认jssecacerts(需管理员权限)
keytool -importcert -alias wiremock-localhost -file wiremock-localhost.cer -keystore $JAVA_HOME/jre/lib/security/jssecacerts -storepass changeit

步骤3:配置WireMock使用自定义证书

在JUnit 4测试类中指定自定义keystore参数:

import com.github.tomakehurst.wiremock.WireMockServer;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;

public class WireMockSslTest {
    private WireMockServer wireMockServer;

    @Before
    public void setup() {
        wireMockServer = new WireMockServer(options()
                .port(8089) // HTTP端口
                .httpsPort(8443) // HTTPS端口
                .keystorePath("wiremock-localhost.jks") // 自定义keystore路径
                .keystorePassword("password") // keystore密码
                .keyManagerPassword("password")); // 密钥密码
        wireMockServer.start();
    }

    @After
    public void teardown() {
        wireMockServer.stop();
    }
}

解决方案2:临时绕过主机名校验(仅测试环境)

如果只是临时测试需求,可通过Java代码禁用SSL主机名校验(绝对禁止在生产环境使用):

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

public class SslUtils {
    public static void disableHostnameVerification() throws Exception {
        // 创建信任所有证书的TrustManager
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() { return null; }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {}
                }
        };

        // 初始化SSLContext
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

        // 禁用主机名校验
        HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
    }
}

在Java客户端发起请求前执行SslUtils.disableHostnameVerification()即可跳过校验。


解决方案3:修改WireMock默认证书(不推荐)

若不想生成新证书,可手动替换WireMock Jar包中的默认证书文件,但操作复杂且易因版本更新失效,不推荐使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 11:27:25