1、 使用java的keytool工具生成证书文件
keytool -genkey -alias michaelkey -keyalg RSA -keysize 1024 -keypass hzfpwd -validity 365 -keystore e:sslmy.ks -storepass hzfpwd
参数说明看下帮助,我这个是照着写的,keypass和storepass 我设成一样的了,keystore为文件存储位置。
2、 将文件拷贝到activemq目录的conf文件夹下。
3、 修改activemq/conf目录下的activemq.xml,加入
<transportConnector name="mqtt+nio" uri="mqtt+nio+ssl://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<sslContext> <sslContext keyStore="file:${activemq.base}/conf/my.ks" keyStorePassword="hzfpwd" trustStore="file:${activemq.base}/conf/my.ks" trustStorePassword="hzfpwd" /> </sslContext>
4、 启动服务,服务器端ssl就ok了。
5、 客户端ssl
我直接考代码了:
package com.via.im.test; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import java.security.GeneralSecurityException; import java.security.KeyStore; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; /** * 获取sslcontext * @author han.zhifeng * */ public class MqttSslTest { /** * 获取sslcontext * @return */ public static SSLContext getSSLContext() { final char[] JKS_PASSWORD = "hzfpwd".toCharArray(); final char[] KEY_PASSWORD = "hzfpwd".toCharArray(); try { /* Get the JKS contents */ final KeyStore keyStore = KeyStore.getInstance("JKS"); try (final InputStream is = new FileInputStream( fullPathOfKeyStore())) { keyStore.load(is, JKS_PASSWORD); } final KeyManagerFactory kmf = KeyManagerFactory .getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(keyStore, KEY_PASSWORD); final TrustManagerFactory tmf = TrustManagerFactory .getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(keyStore); /* * Creates a socket factory for HttpsURLConnection using JKS * contents */ final SSLContext sc = SSLContext.getInstance("TLS"); sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new java.security.SecureRandom()); // final SSLSocketFactory socketFactory = sc.getSocketFactory(); // HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory); return sc; } catch (final GeneralSecurityException | IOException exc) { throw new RuntimeException(exc); } } /** * 证书 * @return */ private static String fullPathOfKeyStore() { final String JKS_RESOURCE_PATH = "/ssl/my.ks"; final URL url = MqttSslTest.class.getResource(JKS_RESOURCE_PATH); try { final Path path = Paths.get(url.toURI()); return path.toAbsolutePath().toString(); } catch (final URISyntaxException exc) { throw new RuntimeException(exc); } } }
Mqtt客户端设置一下就ok了。
MQTT mqtt = new MQTT(); mqtt.setHost("ssl://192.168.254.128:1883"); mqtt.setClientId("hanzhifeng-8"); // 用于设置客户端会话的ID。在setCleanSession(false);被调用时,MQTT服务器利用该ID获得相应的会话。此ID应少于23个字符,默认根据本机地址、端口和时间自动生成 mqtt.setCleanSession(false); // 若设为false,MQTT服务器将持久化客户端会话的主体订阅和ACK位置,默认为true mqtt.setKeepAlive((short) 60);// 定义客户端传来消息的最大时间间隔秒数,服务器可以据此判断与客户端的连接是否已经断开,从而避免TCP/IP超时的长时间等待 mqtt.setUserName("test");// 服务器认证用户名 mqtt.setPassword("test");// 服务器认证密码 mqtt.setWillTopic("willTopic");// 设置“遗嘱”消息的话题,若客户端与服务器之间的连接意外中断,服务器将发布客户端的“遗嘱”消息 mqtt.setWillMessage("willMessage");// 设置“遗嘱”消息的内容,默认是长度为零的消息 mqtt.setWillQos(QoS.AT_LEAST_ONCE);// 设置“遗嘱”消息的QoS,默认为QoS.ATMOSTONCE mqtt.setWillRetain(true);// 若想要在发布“遗嘱”消息时拥有retain选项,则为true mqtt.setVersion("3.1.1"); // 失败重连接设置说明 mqtt.setConnectAttemptsMax(10L);// 客户端首次连接到服务器时,连接的最大重试次数,超出该次数客户端将返回错误。-1意为无重试上限,默认为-1 mqtt.setReconnectAttemptsMax(3L);// 客户端已经连接到服务器,但因某种原因连接断开时的最大重试次数,超出该次数客户端将返回错误。-1意为无重试上限,默认为-1 mqtt.setReconnectDelay(10L);// 首次重连接间隔毫秒数,默认为10ms mqtt.setReconnectDelayMax(30000L);// 重连接间隔毫秒数,默认为30000ms mqtt.setReconnectBackOffMultiplier(2);// 设置重连接指数回归。设置为1则停用指数回归,默认为2 // Socket设置说明 mqtt.setReceiveBufferSize(65536);// 设置socket接收缓冲区大小,默认为65536(64k) mqtt.setSendBufferSize(65536);// 设置socket发送缓冲区大小,默认为65536(64k) mqtt.setTrafficClass(8);// 设置发送数据包头的流量类型或服务类型字段,默认为8,意为吞吐量最大化传输 // 带宽限制设置说明 mqtt.setMaxReadRate(0);// 设置连接的最大接收速率,单位为bytes/s。默认为0,即无限制 mqtt.setMaxWriteRate(0);// 设置连接的最大发送速率,单位为bytes/s。默认为0,即无限制 mqtt.setSslContext(MqttSslTest.getSSLContext());//设置ssl
ok,完事了。