1. 程式人生 > >ActiveMQ SSL應用之四 編寫Java Demo類使用SSL連線ActiveMQ

ActiveMQ SSL應用之四 編寫Java Demo類使用SSL連線ActiveMQ

一、主要內容
在Eclipse平臺編寫Java Demo類使用SSL連線ActiveMQ,並進行簡單的報文傳送,接收,並使用wireshark抓包工具對報文進行抓取分析。

二、Demo類
1、訊息生產者

package example;

import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Session;

import
org.apache.activemq.ActiveMQSslConnectionFactory; /** * 使用SSL聯結器 * 佇列訊息生產者 */ public class SSLPublisher { public static void main(String[] args) throws JMSException, Exception { /* * 配置引數 金鑰和證書檔案的訪問目錄 金鑰密碼 SSL連結地址 */ String keyStore = "E:/ssl/client1.ks"; String trustStore = "E:/ssl/client1.ts"
; String keyStorePassword = "asdfgh"; String url = "ssl://127.0.0.1:61617"; // 建立SSL聯結器工廠類 ActiveMQSslConnectionFactory sslConnectionFactory = new ActiveMQSslConnectionFactory(); // 設定引數,並載入SSL金鑰和證書資訊 sslConnectionFactory.setBrokerURL(url); sslConnectionFactory.setKeyAndTrustManagers(SSLUtils.loadKeyManager(keyStore, keyStorePassword), SSLUtils.loadTrustManager(trustStore), new
java.security.SecureRandom()); // 連線ActiveMQ Connection conn = sslConnectionFactory.createConnection(); conn.start(); Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); Destination dest = session.createQueue("sslDemo"); // 建立訊息生產者,傳送一條報文訊息 MessageProducer mp = session.createProducer(dest); Message msg = session.createTextMessage("Hello SSL!"); mp.send(msg); System.out.println("success"); // 傳送完成,釋放連線 session.close(); conn.close(); } }

2、訊息消費者

package example;

import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQSslConnectionFactory;

/**
 *    使用SSL聯結器
 *    佇列訊息消費者
 */
public class SSLListener {

    public static void main(String[] args) throws JMSException, Exception {
        /*
         * 配置引數 金鑰和證書檔案的訪問目錄 金鑰密碼 SSL連結地址
         */
        String keyStore = "E:/ssl/client1.ks";
        String trustStore = "E:/ssl/client1.ts";
        String keyStorePassword = "asdfgh";
        String url = "ssl://127.0.0.1:61617";

        // 建立SSL聯結器工廠類
        ActiveMQSslConnectionFactory sslConnectionFactory = new ActiveMQSslConnectionFactory();
        // 設定引數,並載入SSL金鑰和證書資訊
        sslConnectionFactory.setBrokerURL(url);
        sslConnectionFactory.setKeyAndTrustManagers(SSLUtils.loadKeyManager(keyStore, keyStorePassword), SSLUtils.loadTrustManager(trustStore),
                new java.security.SecureRandom());

        // 連線ActiveMQ
        Connection conn = sslConnectionFactory.createConnection();
        conn.start();
        Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Destination dest = session.createQueue("sslDemo");
        // 設定訊息消費者,在匿名內部類中列印訊息內容
        MessageConsumer mc = session.createConsumer(dest);
        mc.setMessageListener(new MessageListener() {
            @Override
            public void onMessage(Message msg) {
                if (msg instanceof TextMessage) {
                    try {
                        TextMessage tmsg = (TextMessage) msg;
                        System.out.println(tmsg.getText());
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.out.println(msg.toString());
                }
            }
        });

        // 不關閉連線,讓客戶端一直連著ActiveMQ
    }

}

3、工具類

package example;

import java.io.FileInputStream;
import java.security.KeyStore;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

/**
 * SSL 工具類
 * 載入金鑰和證書檔案
 */
public class SSLUtils {

     /**
      * 載入證書檔案
      * @param trustStore
      * @return
      * @throws java.security.NoSuchAlgorithmException
      * @throws java.security.KeyStoreException
      * @throws java.io.IOException
      * @throws java.security.GeneralSecurityException
      */
     public static TrustManager[] loadTrustManager(String trustStore) throws java.security.NoSuchAlgorithmException, java.security.KeyStoreException,
                java.io.IOException, java.security.GeneralSecurityException {
           KeyStore ks = KeyStore. getInstance("JKS");
           ks.load( new FileInputStream(trustStore), null);
           TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory. getDefaultAlgorithm());
           tmf.init(ks);
           System. out.println( "init TrustManagers finish");
            return tmf.getTrustManagers();
     }

     /**
      * 載入金鑰檔案
      * @param keyStore
      * @param keyStorePassword
      * @return
      * @throws java.security.NoSuchAlgorithmException
      * @throws java.security.KeyStoreException
      * @throws java.security.GeneralSecurityException
      * @throws java.security.cert.CertificateException
      * @throws java.io.IOException
      * @throws java.security.UnrecoverableKeyException
      */
     public static KeyManager[] loadKeyManager(String keyStore, String keyStorePassword) throws java.security.NoSuchAlgorithmException,
                java.security.KeyStoreException, java.security.GeneralSecurityException, java.security.cert.CertificateException, java.io.IOException,
                java.security.UnrecoverableKeyException {
           KeyStore ks = KeyStore. getInstance("JKS");
           ks.load( new FileInputStream(keyStore), keyStorePassword.toCharArray());
           KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory. getDefaultAlgorithm());
           kmf.init(ks, keyStorePassword.toCharArray());
           System. out.println( "init KeyManager finish");
            return kmf.getKeyManagers();
     }
}

三、執行結果
1、生產者,消費者啟動時,檢視ActiveMQ控制檯,在Connections選單下可以看到Connector SSL有兩個連線資訊,如下圖所示:
這裡寫圖片描述

2、ActiveMQ管理控制檯,在Queues選單下可以看到建立名稱為“ sslDemo”的訊息佇列。
3、程式執行結果:佇列消費者端在Eclipse控制檯列印”Hello SSL”。

四、wireshark抓包分析
1、安裝好wireshark,啟動抓包,重複一遍報文傳送,搜尋tcp.port == 61617,追蹤TCP流,發現通訊報文已經全部是密文了,如下圖所示:
這裡寫圖片描述

2、為了對比加密效果,這裡另外發送了一段使用了明文通訊方式的報文(java程式碼略),傳送內容為“Hello Openwire”,搜尋tcp.port == 61616,追蹤TCP流,發現通訊報文可以看到“Hello Openwire ”字樣,如下圖所示:
這裡寫圖片描述