我在客户端使用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
我认为我的客户没有将证书发送给经纪人,但是它是否会自动发送证书? 谢谢你的帮助。
答案 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工厂。
这是最新版本的来源。你可以从
查看旧版本的源代码之后,我必须修改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
如果资源文件夹中ca目录中的所有证书文件都检查exec目录。 我的意思是将您的证书文件放在目录中。
答案 1 :(得分:0)
你在Github中使用我的代码。 您的证书文件似乎没有效果。 确保目录中的所有ca文件都是“./SSL”。 您最好生成ca文件,然后重试。