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

如何禁用HiveMQ MQTT客户端证书验证?解决PKIX路径构建失败

解决方案:禁用HiveMQ MQTT客户端的证书验证

问题背景

连接MQTT Broker(如HiveMQ)时,因未配置信任证书导致SSL握手失败,错误信息如下:

com.hivemq.client.mqtt.exceptions.ConnectionFailedException: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

解决步骤

要跳过证书验证,需自定义一个信任所有证书的SSLContext,并替换HiveMQ客户端的默认SSL配置:

  1. 实现信任所有证书的SSLContext
    创建自定义SSLContext,通过自定义X509TrustManager绕过证书校验逻辑。
  2. 替换MQTT客户端的SSL配置
    在协议配置方法中,使用自定义SSLContext替代默认的SSL配置。

修改后的完整代码

public @ResponseBody GenericResponse testMqttConnection(
      @RequestBody AdvancedMQTTSetting mqttSetting, HttpServletRequest request) {

    GenericResponse response = new GenericResponse();

    /*
     * Initialize the client builder with common settings
     */
    MqttClientBuilder clientBuilder =
        MqttClient.builder()
            .identifier(Utils.generateUUID())
            .serverAddress(
                new InetSocketAddress(mqttSetting.getBrokerUrl(), mqttSetting.getPort()));

    try {
      if (mqttSetting.getMqttVersion().equals(PayloadMqttVersion.VERSION_5_0)) {
        /*
         * Configure MQTT 5 client
         */
        Mqtt5ClientBuilder mqtt5ClientBuilder = clientBuilder.useMqttVersion5();
        mqtt5ClientBuilder
            .simpleAuth()
            .username(mqttSetting.getUsername())
            .password(mqttSetting.getPassword().getBytes(StandardCharsets.UTF_8))
            .applySimpleAuth();

        /*
         * Apply Protocol Specific Settings
         */
        applyProtocolSpecificSettings(mqtt5ClientBuilder, mqttSetting);

        Mqtt5BlockingClient mqtt5Client = mqtt5ClientBuilder.buildBlocking();
        Mqtt5ConnAck connAck = mqtt5Client.connect();
        /*
         * Handle Connection Result
         */
        handleConnectionResult(
            response,
            connAck.getReasonCode() == Mqtt5ConnAckReasonCode.SUCCESS,
            (MqttBlockingClient) mqtt5Client);

      } else {
        /*
         * Configure MQTT 3 client
         */
        Mqtt3ClientBuilder mqtt3ClientBuilder = clientBuilder.useMqttVersion3();
        mqtt3ClientBuilder
            .simpleAuth()
            .username(mqttSetting.getUsername())
            .password(mqttSetting.getPassword().getBytes(StandardCharsets.UTF_8))
            .applySimpleAuth();
        /*
         * Apply Protocol Specific Settings
         */
        applyProtocolSpecificSettings(mqtt3ClientBuilder, mqttSetting);

        Mqtt3BlockingClient mqtt3Client = mqtt3ClientBuilder.buildBlocking();
        Mqtt3ConnAck connAck = mqtt3Client.connect();
        /*
         * Handle Connection Result
         */
        handleConnectionResult(
            response,
            connAck.getReturnCode() == Mqtt3ConnAckReturnCode.SUCCESS,
            (MqttBlockingClient) mqtt3Client);
      }
    } catch (Exception e) {
      LOGGER.error(e.getMessage(), e);
      response.setError(true);
      response.setErrorMessage(StringConstants.CONNECTION_UNSUCCESSFULL);
    }

    return response;
  }

  private void applyProtocolSpecificSettings(
      MqttClientBuilderBase<?> clientBuilder, AdvancedMQTTSetting mqttSetting) {

    if (PayloadProtocolType.WS.equals(mqttSetting.getProtocolType())
        || PayloadProtocolType.WSS.equals(mqttSetting.getProtocolType())) {
      clientBuilder.webSocketConfig(
          MqttWebSocketConfig.builder()
              .serverPath(mqttSetting.getServerPath())
              .subprotocol("mqtt")
              .build());
    }

    if (PayloadProtocolType.MQTTS.equals(mqttSetting.getProtocolType())
        || PayloadProtocolType.WSS.equals(mqttSetting.getProtocolType())) {
      // 使用自定义SSLContext替代默认配置
      clientBuilder.sslConfig(MqttSslConfig.builder().sslContext(createTrustAllSslContext()).build());
    }
  }

  private static SSLContext createTrustAllSslContext() {
    try {
      // 创建信任所有证书的TrustManager
      X509TrustManager trustAllManager = new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) {}

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) {}

        @Override
        public X509Certificate[] getAcceptedIssuers() {
          return new X509Certificate[0];
        }
      };

      SSLContext sslContext = SSLContext.getInstance("TLS");
      sslContext.init(null, new TrustManager[]{trustAllManager}, new SecureRandom());
      return sslContext;

    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException("Failed to create trust-all SSLContext", e);
    }
  }

注意事项

  • 仅测试环境使用:此方式完全跳过证书验证,会导致通信失去SSL安全保障,生产环境必须配置合法的信任证书,禁止使用该方案。
  • 生产环境连接自签名证书Broker时,正确做法是将Broker证书导入客户端信任库(如JKS文件),而非禁用验证。

内容的提问来源于stack exchange,提问作者P SAI KIREETI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:42:33