版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huangying2124/article/details/52833307
一、主要内容
在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 ”字样,如下图所示: