0

我使用此链接创建自签名根 CA 证书和服务器密钥对

使用此链接使用先前生成的根证书生成客户端密钥对

虽然这些链接是为 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&amp;wireFormat.maxInactivityDuration=300000&amp;wireFormat.maxFrameSize=104857600&amp;jms.messagePrioritySupported=false"/>
        <transportConnector name="ssl" uri="ssl://0.0.0.0:61714?trace=true&amp;needClientAuth=true&amp;transport.enabledProtocols=TLSv1.2"/>
        <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="mqtt+ssl" uri="mqtt+ssl://0.0.0.0:8883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;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;
}
4

1 回答 1

1

回答我自己的问题。下面是keystore/truststore及其内容的映射

  • 代理密钥库:捆绑到 PKCS12 文件中的服务器密钥对
  • 代理信任库:根证书
  • 客户端密钥库:捆绑到 PKCS12 文件中的客户端密钥对
  • 客户端信任库:根证书

这是正确的配置,现在一切正常。不完全确定为什么关于为 MQTT 配置证书的内容很少。我查看了一堆 HTTPS 示例,了解到必须将证书添加到密钥库和信任库中,如上所示。

于 2020-07-09T10:05:56.273 回答