Activemq 使用ssl说明

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&amp;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,完事了。

原文地址:https://www.cnblogs.com/momofeng/p/5455363.html