Set2017 2024-08-01 09:52 采纳率: 0%
浏览 13
已结题

java MQTT SSL证书

java mqtt SSL证书认证连接时,提示 is not a CA certificate,开发环境运行正常,生产环境连接出错
生产系统版本:CentOS Linux release 8.4.2105,开发环境:window10
核心代码:
public void start() {
        String serverUrl = "ssl://*****:5698";
        String caCrtFile = "/usr/local/web/ssl/caCert.pem";
        String crtFile = "/usr/local/web/ssl/Jd3BCq_cert.txt";
        String keyFile = "/usr/local/web/ssl/Jd3BCq_keys.txt";
        try {
            MqttClient client = new MqttClient(serverUrl,
                    "T" + System.currentTimeMillis(), new MemoryPersistence());
            MqttConnectOptions options = new MqttConnectOptions();
            options.setCleanSession(true);
            //设置超时时间
            options.setConnectionTimeout(10);
            //设置回话心跳时间
            options.setKeepAliveInterval(20);
            options.setHttpsHostnameVerificationEnabled(false);
            SSLSocketFactory factory = SslUtil.getSocketFactory(
                    caCrtFile, crtFile, keyFile, "");
            options.setSocketFactory(factory);
            client.connect(options);
            System.out.println("服务端已运行");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

springboot pom.xml:
<dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.18.0</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.paho</groupId>
            <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
            <version>1.2.1</version>
        </dependency>
        <dependency>
            <groupId>bouncycastle</groupId>
            <artifactId>bcprov-jdk15</artifactId>
            <version>140</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

生产环境调用出现错误:
MqttException (0) - javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "EMAILADDRESS=iot@baidu.com, CN=2021-q1-unstack, OU=iot, O=Default Company Ltd, ST=Beijing, C=CN" is not a CA certificate
    at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:736)
    at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "EMAILADDRESS=iot@baidu.com, CN=2021-q1-unstack, OU=iot, O=Default Company Ltd, ST=Beijing, C=CN" is not a CA certificate
    at sun.security.ssl.Alert.createSSLException(Alert.java:131)
    at sun.security.ssl.TransportContext.fatal(TransportContext.java:353)
    at sun.security.ssl.TransportContext.fatal(TransportContext.java:296)
    at sun.security.ssl.TransportContext.fatal(TransportContext.java:291)
    at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:652)
    at sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:471)
    at sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:367)
    at sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:376)
    at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
    at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:422)
    at sun.security.ssl.TransportContext.dispatch(TransportContext.java:183)
    at sun.security.ssl.SSLTransport.decode(SSLTransport.java:154)
    at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1279)
    at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1188)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:401)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:373)
    at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:149)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:722)
    ... 1 more
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "EMAILADDRESS=iot@baidu.com, CN=2021-q1-unstack, OU=iot, O=Default Company Ltd, ST=Beijing, C=CN" is not a CA certificate
    at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:369)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:275)
    at sun.security.validator.Validator.validate(Validator.java:271)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:312)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:221)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:128)
    at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:636)
    ... 14 more
Caused by: sun.security.validator.ValidatorException: TrustAnchor with subject "EMAILADDRESS=iot@baidu.com, CN=2021-q1-unstack, OU=iot, O=Default Company Ltd, ST=Beijing, C=CN" is not a CA certificate
    at sun.security.validator.PKIXValidator.verifyTrustAnchor(PKIXValidator.java:393)
    at sun.security.validator.PKIXValidator.toArray(PKIXValidator.java:333)
    at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:366)
    ... 20 more

已尝试运行时增加后缀“-Djdk.security.allowNonCaAnchor=true”,依然无效,有遇到过的学友指点迷津,谢谢!
  • 写回答

19条回答 默认 最新

  • 笑面虎 2024-08-01 09:53
    关注

    以下内容由AIGC及笑面虎共同生成、有用望采纳:


    根据您提供的信息,您在生产环境中遇到的问题是SSL证书验证失败,具体错误提示为“is not a CA certificate”。这通常意味着客户端在SSL握手过程中无法验证服务器证书的有效性,可能是因为证书链不完整或证书不被信任。

    以下是解决这个问题的步骤和建议:

    1. 验证证书链

    确保服务器证书是由一个受信任的CA签发的,并且证书链是完整的。您可以使用以下命令来验证证书链:

    openssl verify -CAfile caCert.pem serverCert.pem
    

    这里的caCert.pem是根证书文件,serverCert.pem是服务器证书文件。

    2. 导入CA证书到Java信任存储

    如果生产环境的Java信任存储中没有包含签发服务器证书的CA证书,您需要将其导入。可以使用keytool命令行工具来完成:

    keytool -import -alias myCA -keystore /path/to/java/truststore -file caCert.pem
    

    请替换/path/to/java/truststore为实际的信任存储路径,caCert.pem为CA证书文件。

    3. 检查代码中的证书文件路径

    确保caCrtFilecrtFilekeyFile变量指向的路径是正确的,并且这些文件是可访问的。

    4. 使用正确版本的Bouncy Castle库

    您使用的bcprov-jdk15可能与您的Java版本不兼容。请检查您的Java版本,并使用与之对应的Bouncy Castle库版本。

    5. 重新启用主机名验证

    禁用主机名验证会降低安全性,如果可能,请重新启用它:

    options.setHttpsHostnameVerificationEnabled(true);
    

    6. 增加日志记录

    在代码中增加日志记录,以便于捕获SSL握手过程中的详细信息,这有助于诊断问题。

    示例代码

    以下是修改后的代码示例,假设证书链验证无误,证书文件路径正确,并且Bouncy Castle库版本兼容:

    public void start() {
        String serverUrl = "ssl://*****:5698";
        String caCrtFile = "/path/to/caCert.pem"; // 确保路径正确
        String crtFile = "/path/to/Jd3BCq_cert.txt";
        String keyFile = "/path/to/Jd3BCq_keys.txt";
        try {
            MqttClient client = new MqttClient(serverUrl,
                    "T" + System.currentTimeMillis(), new MemoryPersistence());
            MqttConnectOptions options = new MqttConnectOptions();
            options.setCleanSession(true);
            options.setConnectionTimeout(10);
            options.setKeepAliveInterval(20);
            options.setHttpsHostnameVerificationEnabled(true); // 重新启用主机名验证
            
            SSLSocketFactory factory = SslUtil.getSocketFactory(
                    caCrtFile, crtFile, keyFile, "");
            options.setSocketFactory(factory);
            client.connect(options);
            System.out.println("服务端已运行");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    假设数据和示例输入输出

    • 假设数据:证书文件caCert.pemJd3BCq_cert.txtJd3BCq_keys.txt都位于正确的路径,并且是有效的。
    • 示例输入:用户执行start()方法,尝试连接到MQTT服务器。
    • 示例输出:如果连接成功,控制台输出“服务端已运行”;如果失败,打印异常堆栈信息。

    注意事项

    • 确保在生产环境中正确配置了Java的信任存储,并且所有必要的证书都已经导入。
    • 如果问题依旧存在,可能需要进一步检查网络配置、防火墙设置或与证书颁发机构联系获取正确的证书链。

    希望这些建议能帮助您解决生产环境中的SSL证书问题。如果还有其他问题或需要进一步的帮助,请随时提问。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 8月9日
  • 创建了问题 8月1日

悬赏问题

  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见
  • ¥15 一共有五道问题关于整数幂的运算还有房间号码 还有网络密码的解答?(语言-python)
  • ¥20 sentry如何捕获上传Android ndk 崩溃
  • ¥15 在做logistic回归模型限制性立方条图时候,不能出完整图的困难
  • ¥15 G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?