ActiveMQ SSL應用之四 編寫Java Demo類使用SSL連線ActiveMQ
阿新 • • 發佈:2018-11-01
一、主要內容
在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 ”字樣,如下圖所示: