TLS与mosquitto连接错误

时间:2017-06-07 01:50:31

标签: ssl mqtt

我在客户端使用mosquitto作为经纪人和Paho。当与tcp连接时,一切似乎都没问题,然后我想使用TLS,这就是问题所在。 我首先生成ca.key,ca.crt,然后我用它来生成server.crt,server.key,client.crt,client.key;然后我尝试使用https://github.com/Lunatictwo/mqtt-ssl-java中的代码,这里是'我的代码:

public static void main(String[] args) {
    // TODO Auto-generated method stub
    String address = "ssl://192.168.100.46:8883";
    String topic = "topic0";
    String caFilePath = "SSL/ca.crt";
    String clientCrtFilePath = "SSL/client.crt";
    String clientKeyFilePath = "SSL/client.key";
    String keyPassword = "1234567890";
    MemoryPersistence persistence = new MemoryPersistence();
    try {
        MqttConnectOptions options = new MqttConnectOptions();
        options.setCleanSession(false);
        options.setSocketFactory(SslUtil.getSocketFactory(caFilePath,clientCrtFilePath,clientKeyFilePath,keyPassword));

        MqttClient client;          
        client = new MqttClient(address,"java-client",persistence);
        client.connect(options);
        client.subscribe(topic);
        client.setCallback(new MyCallback());

        MqttMessage message = new MqttMessage();
        message.setPayload("MosquittoClient连接成功".getBytes());
        client.publish(topic,message);

        client.disconnect();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

当我运行这个演示时,我在mosquitto中得到了这个:

New connection from 192.168.100.46 on port 8883.
1496799343: OpenSSL Error: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
1496799343: Socket error on client (null), disconnecting.
1496799343: New connection from 192.168.100.46 on port 8883.
1496799343: OpenSSL Error: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
1496799343: Socket error on client (null), disconnecting.

以下是eclipse中的信息:

MqttException (0) - java.net.SocketException: Software caused connection abort: socket write error
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:690)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at sun.security.ssl.OutputRecord.writeBuffer(OutputRecord.java:431)
at sun.security.ssl.OutputRecord.write(OutputRecord.java:417)
at sun.security.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:876)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:847)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:717)
at sun.security.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:1077)
at sun.security.ssl.ClientHandshaker.sendChangeCipherAndFinish(ClientHandshaker.java:1222)
at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1134)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:348)
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:97)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:676)
... 1 more

我认为我的客户没有将证书发送给经纪人,但是它是否会自动发送证书? 谢谢你的帮助。

2 个答案:

答案 0 :(得分:0)

使用SSL / TLS的MQTT(Mosquitto)

我的发展环境是 使用mqtt协议将mosquitto服务器保护为消息队列代理 和openssl的eclipse paho客户端。

您可以查看我的github

以下是我对这些内容所做的事情。

使用openssl库通过脚本(OwnTracks)创建自己的证书文件。

使用wget命令下载generate-CA.sh脚本,如下所示

mkdir CA
chmod 700 CA
cd CA

wget https://github.com/owntracks/tools/raw/master/TLS/generate-CA.sh .
./generate-CA.sh

您可以检查在执行脚本时创建的所有6个文件:

ca.crt(certificates), ca.key(keys), ca.srl(serial number record),
localhost.crt, localhost.csr(request), localhost.key

sudo cp ca.crt /etc/mosquitto/ca
sudo cp localhost.crt localhost.key /etc/mosquitto/crt/
  

配置mosquitto.conf

vi /usr/local/mosquitto/mosquitto.conf 

将下面的行放在文件末尾

listener 8883
protocol mqtt

cafile /etc/mosquitto/ca/ca.crt
certfile /etc/mosquitto/crt/localhost.crt
keyfile /etc/mosquitto/crt/localhost.key

require_certificate false   

#listener 1883  => all refuse except TLS secure connection.
#protocol mqtt

您现在可以在bin文件夹中看到mosquitto_sub和mosquitto_pub可执行文件的内容

启动经纪人

mosquitto -c mosquitto.conf 

开始订阅
mosquitto_sub -h localhost -p 8883 --cafile /etc/mosquitto/ca_certficates/ca.crt -t hello

开始发布 mosquitto_pub -h localhost -p 8883 --cafile /etc/mosquitto/ca_certficates/ca.crt-t hello -m" Test is Test"

现在,是时候准备好java客户端了。

从eclipse paho网站获取java客户端

https://github.com/eclipse/paho.mqtt.java

我决定用ant项目创建自己的paho客户端。 我也使用apache启动器项目。

- apache-ant-1.9.4
- apache launcher

你应该有一些像网站bouncycastle这样的openssl java库 https://www.bouncycastle.org/latest_releases.html

- bcpkix-jdk15on-157.jar
- bcprov-ext-jdk15on-157.jar
- bcprov-jdk15on-156.jar

完成所有这些设置后,我找到了一个名为SslUtil.java的sslsocket工厂。

  

https://gist.github.com/rohanag12/07ab7eb22556244e9698

这是最新版本的来源。你可以从

查看旧版本的源代码
  

https://gist.github.com/sharonbn/4104301

之后,我必须修改Sample.java。 有比原始选项更多的选项。

输入帮助命令时的输出。

Syntax:

Sample [-h] [-a publish|subscribe] [-t <topic>] [-m <message text>]
[-s 0|1|2] -b <hostname|IP address>] [-p <brokerport>] [-i <clientID>]

-h  Print this help text and quit
-q  Quiet mode (default is false)
-a  Perform the relevant action (default is publish)
-v  TLS/SSL enabled; true - (default is false)
-e  Path of ca certification file if v option turns on
-f  Path of client certification file if v option turns on
-y  Path of client key file if v option turns on
-t  Publish/subscribe to <topic> instead of the default
(publish: "Sample/Java/v3", subscribe: "Sample/#")
-m  Use <message text> instead of the default
("Message from MQTTv3 Java client")
-s  Use this QoS instead of the default (2)
-b  Use this name/IP address instead of the default (m2m.eclipse.org)
-p  Use this port instead of the default (1883)

-i  Use this client ID instead of SampleJavaV3_<action>
-c  Connect to the server with a clean session (default is false)


Security Options
-u Username
-z Password


TLS Options
-v  TLS/SSL enabled; true - (default is false)     -e  CA certification file with openssl generally
-f  Client certification file
-y  Client key file

然后,您可以使用apache启动器执行mqtt客户端。 请参阅 launcher.xml 和几个批处理脚本。 我假设您的操作系统必须是Windows,但在您的操作系统上找到兼容命令并不困难。

我的launcher.xml文件中的Jvm参数如下。

<强>订阅: -a subscribe -b 192.9.112.155 -p 8883 -e resources / ca /​​ ca.crt -f resources / ca /​​ wap1.crt -y resources / ca /​​ wap1.key -v true -z secret 的发布: -a publish -b 192.9.112.155 -p 8883 -e resources / ca /​​ ca.crt -f resources / ca /​​ wap1.crt -y resources / ca /​​ wap1.key -v true -z secret -m&#39;这是来自我的消息&#39;

最后,我的子/ pub在这里登录。

>SET JAVA_HOME=C:\DEV\COMP\Java\jdk1.8.0_111

>SET ANT_HOME=C:\DEV\Tools\apache-ant-1.9.4

>SET CLASSPATH=.

>java -cp . LauncherBootstrap -verbose -executablename mqtt_paho_simple_subscriber mqtt_paho_simple_subscriber_secure
>>>>>>>>>>>>>>Encrypted key - we will use provided password
tlsmode.. true ...connection to ssl://xxx.xxx.xxx.xxx:8883
Connected to ssl://xxx.xxx.xxx.xxx:8883 with client ID SampleJavaV3_subscribe
Subscribing to topic "Sample/#" qos 2
Press <Enter> to exit
Time:   2017-07-19 19:40:17.594  Topic: Sample/Java/v3  Message:        this is a message from me  QoS: 2


>java -cp . LauncherBootstrap -verbose -executablename mqtt_paho_simple_publisher mqtt_paho_simple_publisher_secure
>>>>>>>>>>>>>>Encrypted key - we will use provided password
tlsmode.. true ...connection to ssl://xxx.xxx.xxx.xxx:8883
Connecting to ssl://xxx.xxx.xxx.xxx:8883 with client ID SampleJavaV3_publish
Connected
Publishing at: 2017-07-19 19:40:17.562 to topic "Sample/Java/v3" qos 2
Disconnected

enter image description here enter image description here

注意:

如果资源文件夹中ca目录中的所有证书文件都检查exec目录。 我的意思是将您的证书文件放在目录中。

答案 1 :(得分:0)

你在Github中使用我的代码。 您的证书文件似乎没有效果。 确保目录中的所有ca文件都是“./SSL”。 您最好生成ca文件,然后重试。