虽然这些链接是为 MosquittoMQ 设置 SSL 而我的用例是为 ActiveMQ,但我相信证书生成过程对于这两种情况都是一样的。
我使用的客户端是 Java 客户端。根据密钥库的要求,代理密钥库包含捆绑到 PKCS12 文件中的根证书和服务器公钥和私钥,代理信任库包含客户端的公钥。客户端密钥库包含捆绑到 PKCS12 文件中的客户端公钥和私钥,客户端信任库包含根证书。Java 客户端使用端口 61714 连接到代理。通过以上配置的密钥库和信任库,我得到了空证书链异常。有人可以告诉我这是否是配置密钥和信任存储的正确方法吗?根证书和服务器证书是否应该链接起来,而不是单独存在于代理密钥库中?我对此很陌生,有点迷茫。
ActiveMQ 代理的传输连接器配置如下所示
<managementContext>
<managementContext createConnector="false"/>
</managementContext>
<sslContext>
<sslContext keyStore="file:${activemq.base}/conf/broker.ks"
keyStorePassword="changeit" trustStore="file:${activemq.base}/conf/broker.ts"
trustStorePassword="changeit"/>
</sslContext>
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxInactivityDuration=300000&wireFormat.maxFrameSize=104857600&jms.messagePrioritySupported=false"/>
<transportConnector name="ssl" uri="ssl://0.0.0.0:61714?trace=true&needClientAuth=true&transport.enabledProtocols=TLSv1.2"/>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt+ssl" uri="mqtt+ssl://0.0.0.0:8883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
Java 客户端上的 application.properties 文件
# Embedded ActiveMQ Configuration
spring.activemq.in-memory=false
spring.activemq.pool.enabled=false
activemq.broker-url=tcp://localhost:61616
activemq.ssl-url=ssl://localhost:61714
# Spring JMS Settings
#spring.jms.pub-sub-domain=true
# Truststore used by client.
JMS_BROKER_TRUSTSTORE=E:\\apacheActiveMQ\\apache-activemq-5.13.0\\conf\\client.ts
JMS_BROKER_TRUSTSTORE_TYPE=JKS
JMS_BROKER_TRUSTSTORE_PASSWORD=changeit
# Keystore used by client.
JMS_BROKER_KEYSTORE=E:\\apacheActiveMQ\\apache-activemq- 5.13.0\\conf\\client.ks
JMS_BROKER_KEYSTORE_TYPE=JKS
JMS_BROKER_KEYSTORE_PASSWORD=changeit
处理在 Java 客户端上配置 ActiveMQ 连接工厂的文件
@Bean
public ActiveMQSslConnectionFactory activeMQSslConnectionFactory() {
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory(sslUrl);
try {
connectionFactory.setTrustStore(pathToTrustStore);
connectionFactory.setTrustStorePassword(truststorePassword);
connectionFactory.setKeyStore(pathToKeystore);
connectionFactory.setKeyStorePassword(keystorePassword);
} catch (Exception e) {
System.out.println("Error");
}
return connectionFactory;
}
/**
* Initialise {@link JmsTemplate} as required
*/
@Bean
public JmsTemplate jmsTemplate() {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(activeMQSslConnectionFactory());
jmsTemplate.setExplicitQosEnabled(true);
//setting PuSubDomain to true configures JmsTemplate to work with topics instead of queues
jmsTemplate.setPubSubDomain(true);
jmsTemplate.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
return jmsTemplate;
}
/**
* Initialise {@link DefaultJmsListenerContainerFactory} as required
*/
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(activeMQSslConnectionFactory());
//setting PuSubDomain to true configures the DefaultJmsListenerContainerFactory to work with topics instead of queues
factory.setPubSubDomain(true);
return factory;
}