Java 使用MOSQUITO代理的mqtt中的SSL
我使用MQTT MOSQUITO代理并使用SSL证书进行身份验证。 我面临如下问题,请检查一下Java 使用MOSQUITO代理的mqtt中的SSL,java,ssl-certificate,mqtt,mosquitto,Java,Ssl Certificate,Mqtt,Mosquitto,我使用MQTT MOSQUITO代理并使用SSL证书进行身份验证。 我面临如下问题,请检查一下 java.io.IOException: unrecognised object: TRUSTED CERTIFICATE at org.bouncycastle.openssl.PEMParser.readObject(Unknown Source) at com.iot.mqtt.client.SslUtil.getSocketFactory(SslUtil.java:50) at com.iot
java.io.IOException: unrecognised object: TRUSTED CERTIFICATE
at org.bouncycastle.openssl.PEMParser.readObject(Unknown Source)
at com.iot.mqtt.client.SslUtil.getSocketFactory(SslUtil.java:50)
at com.iot.mqtt.client.Publisher.start(Publisher.java:40)
at com.iot.mqtt.client.Publisher.main(Publisher.java:81)
MqttException (0) - javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:34)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:553)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.net.ssl.SSLHandshakeException: 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.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:84)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:538)
我使用的代码如下所示
private static final String caFile = "D:\\Srini_10568\\IOT\\Mosquitto\\ca.crt";
private static final String caCrtFile = "D:\\Srini_10568\\IOT\\Mosquitto\\cacrt.crt";
private static final String clientKeyFile = "D:\\Srini_10568\\IOT\\Mosquitto\\client.key";
public static final String BROKER_URL = "ssl://123.12.123.12:1883";
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(false);
options.setSocketFactory(SslUtil.
getSocketFactory(caFile,caCrtFile, clientKeyFile, null));
SslUtil.getSocketFactory方法包含以下代码
reader = new PEMParser(new FileReader(crtFile));
X509CertificateHolder certHolder = (X509CertificateHolder) reader.readObject();
reader.close();
X509Certificate cert = certificateConverter.getCertificate(certHolder);
您的*.crt文件可能具有DER格式。您可以尝试使用或使用openssl将证书文件转换为PEM格式
openssl x509 -inform der -in certificate.cer -out certificate.pem
如果使用SSL进行客户端身份验证,则服务器中使用的CA文件必须包含所有客户端证书 在客户端,CA文件包含服务器的证书 在类似您的场景中,您将拥有以下文件:
- server-key.pem
- 客户端{#}-key.pem
- server-cert.pem
- 客户端{#}-cert.pem
- server-ca.pem(包含所有客户端{#}-cert.pem)
- 客户端{#}-ca.pem(包含server-cert.pem,基本上是它的副本)
#
是客户ID或号码,如果您愿意的话
您可以使用以下方法生成所有密钥/证书集:
openssl genrsa-out-key.pem 2048
openssl-req-new-sha256-key-key.pem-out-csr.pem-days
opensslx509-req-in-csr.pem-signkey-key.pem-out-cert.pem
每次生成新的客户端证书时,必须将其内容转储到服务器的CA中,以便服务器能够将其识别为受信任的设备
cat-cert.pem[-cert.pem][…]>ca-cert.pem
我的问题得到解决。它的问题是java库没有识别cacrt.crt文件begin字符串,一旦我删除了它正在工作的可信字符串。玩得开心。抓得好
其java库似乎有识别客户端证书启动参数的限制:-
"-----BEGIN TRUSTED CERTIFICATE-----"
希望下一个版本能对此进行修复。这是bouncy castle中的一个bug,报告如下: 它已在2014年7月发布的v1.51中修复,因此您可能使用了bouncy castle的一个非常旧的版本(超过2年) 下面是一些使用bouncy castle最新版本的示例代码:
它已经是CRT格式,在线工具中没有CRT的输入格式类型。我不明白*.cer文件或我的java代码有什么问题。我使用的代码来自这里(),他在这里执行从client.cer到X509CertificateHolder的转换。但您建议查看证书生成级别。我很困惑。您是使用SSL进行客户端身份验证还是仅用于安全数据传输?这是有区别的。假设是前者,正如您在问题中提到的,并且深入到链接中,服务器中的
cafile
必须包含client.crt
,客户端中的cafile
必须包含server.crt
。到目前为止,它仅用于客户端身份验证。我将检查服务器中cafile的可用性,以便有一次client.crt。为什么这是经过验证的答案?错误甚至不是来自jdk,而是来自bouncy castle。