简体   繁体   中英

connection wrong in TLS with mosquitto

I'm using mosquitto as broker and Paho in client.when connect with tcp,all seems to be okay,and then I want to use TLS,here comes the problem. I first generated ca.key,ca.crt,then I use it to generated server.crt,server.key,client.crt,client.key;then I tried to us code in https://github.com/Lunatictwo/mqtt-ssl-java ,here's my code:

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();
    }
}

and when I run this demo,I got this in 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.

Here's the info in 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

it semms that my client didn't send its certificate to the broker,but shoudn't it send certificate automatically? thank you for your help.

MQTT(Mosquitto) with SSL/TLS

My environment of developement is secure mosquitto server as a message queue broker with mqtt protocol and the eclipse paho client with openssl.

You can check my github

Here is what I've done with these stuffs.

Making a your own certificate file by script(OwnTracks) with openssl library.

Download a generate-CA.sh script using wget command as follows

mkdir CA
chmod 700 CA
cd CA

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

You can check the all 6 files are created while executing the script which are :

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/

configuration of mosquitto.conf

vi /usr/local/mosquitto/mosquitto.conf 

Put the lines below at the end the file

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

You can see now what you have with mosquitto_sub and mosquitto_pub executable in the bin folder

Start Broker

mosquitto -c mosquitto.conf 

start Subscribe
mosquitto_sub -h localhost -p 8883 --cafile /etc/mosquitto/ca_certficates/ca.crt -t hello

start Publish mosquitto_pub -h localhost -p 8883 --cafile /etc/mosquitto/ca_certficates/ca.crt -t hello -m "Test is Test"

Now, It's time to ready with java client.

Getting java client from the eclipse paho site

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

I decided to make my own paho client with ant project. I also use the apache launcher project.

- apache-ant-1.9.4
- apache launcher

You should have some openssl java library like bouncycastle from the site https://www.bouncycastle.org/latest_releases.html

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

After all this setup done, I've got a sslsocket factory named SslUtil.java.

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

This is latest version source. you can check old version of source from

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

After that, I have to modify the Sample.java. There are more options than the original one.

The output when enter the help command.

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

You can then execute mqtt client using apache launcher. See the launcher.xml and several batch scripts. I assume your os must be windows, but it's not that difficult to find compatible command on your os out there.

Jvm arguments in my launcher.xml file as follows.

subscribe : -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 publish : -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 'this is a message from me'

Finally, My sub/pub log here.

>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

在此处输入图片说明 在此处输入图片说明

note:

Check exec directory if all certificate files in the ca directory in the resources folder. I mean put the your cert files to the directory.

you are using my code in Github. It seems that your cert files didn't effect. Make sure all your ca files in your directory "./SSL". You'd better generate ca files and try again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM