【问题标题】:Qpid and JNDI for encrypted messages用于加密消息的 Qpid 和 JNDI
【发布时间】:2017-07-25 10:18:57
【问题描述】:

我目前正在处理一个 JMS 项目,我已经创建了 2 个密钥和 2 个证书以及一个 TrustStorage,我通过 Qpid 的 UI 创建了 mytruststore。 在我的 jndi.properties 文件中,我有以下代码:

//Set the InitialContextFactory class to use

java.naming.factory.initial = org.apache.qpid.jms.jndi.JmsInitialContextFactory

//Define the required ConnectionFactory instances
//connectionfactory.<JNDI-lookup-name> = <URI>

connectionfactory.myFactoryLookup = amqp://localhost:5672
connectionfactory.producerConnectionFactory = amqp://admin:admin@?brokerlist='tcp://localhost:5672?encryption_remote_trust_store='$certificates%255c/mytruststore''
connectionfactory.consumer1ConnectionFactory = amqp://admin:admin@?brokerlist='tcp://localhost:5672?encryption_key_store='C:\OpenSSL-Win64\bin\mytruststorage.jks'&encryption_key_store_password='thanos''
connectionfactory.consumer2ConnectionFactory = amqp://admin:admin@?brokerlist='tcp://localhost:5672?encryption_key_store='C:\OpenSSL-Win64\bin\mytruststorage.jks'&encryption_key_store_password='thanos''

//Configure the necessary Queue and Topic objects
//queue.<JNDI-lookup-name> = <queue-name>
//topic.<JNDI-lookup-name> = <topic-name>

queue.myQueueLookup = queue
topic.myTopicLookup = topic
queue.myTestQueue = queue

在我的 EncryptionExample.java 类中,我有以下代码:

package org.apache.qpid.jms.example;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EncryptionExample {
    public EncryptionExample() {
    }

    public static void main(String[] args) throws Exception {
        EncryptionExample encryptionExampleApp = new EncryptionExample();
        encryptionExampleApp.runProducerExample();
        encryptionExampleApp.runReceiverExample();
    }

    private void runProducerExample() throws Exception
    {
        Connection connection = createConnection("producerConnectionFactory");
        try {
            Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
            Destination destination = createDesination("myTestQueue");

            MessageProducer messageProducer = session.createProducer(destination);
            TextMessage message = session.createTextMessage("Hello world!");

            // ============== Enable encryption for this message ==============
            message.setBooleanProperty("x-qpid-encrypt", true);
            // ============== Configure recipients for encryption ==============
            message.setStringProperty("x-qpid-encrypt-recipients", "CN=client1, OU=Qpid, O=Apache, C=US");

            messageProducer.send(message);
            session.commit();
        }
        finally {
            connection.close();
        }
    }

    private void runReceiverExample() throws Exception
    {
        Connection connection = createConnection("consumer1ConnectionFactory");
        try {
            connection.start();
            Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
            Destination destination = createDesination("myTestQueue");
            MessageConsumer messageConsumer = session.createConsumer(destination);
            Message message = messageConsumer.receive();
            if (message instanceof TextMessage) {
                // application logic
                System.out.println(((TextMessage) message).getText());
            } else if (message instanceof BytesMessage) {
                // handle potential decryption failure
                System.out.println("Potential decryption problem. Application not in list of intended recipients?");
            }
            session.commit();
        }
        finally {
            connection.close();
        }
    }

    ///////////////////////////////////////
    // The following is boilerplate code //
    ///////////////////////////////////////

    private Connection createConnection(final String connectionFactoryName) throws JMSException, IOException, NamingException
    {
        try (InputStream resourceAsStream = getResourceAsStream("jndi.properties")) {
            Properties properties = new Properties();
            properties.load(resourceAsStream);
            Context context = new InitialContext(properties);
            ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup(connectionFactoryName);
            final Connection connection = connectionFactory.createConnection();
            context.close();
            return connection;
        }
    }

    private InputStream getResourceAsStream(String string) {
        // TODO Auto-generated method stub
        return null;
    }

    private Destination createDesination(String desinationJndiName) throws IOException, NamingException
    {
        try (InputStream resourceAsStream = this.getClass().getResourceAsStream("example.properties")) {
            Properties properties = new Properties();
            properties.load(resourceAsStream);
            Context context = new InitialContext(properties);
            Destination destination = (Destination) context.lookup(desinationJndiName);
            context.close();
            return destination;
        }
    }
}

当我尝试构建它时,出现以下异常。

线程“主”java.lang.NullPointerException 中的异常

在 java.util.Properties$LineReader.readLine(Unknown Source)

在 java.util.Properties.load0(未知来源)

在 java.util.Properties.load(Unknown Source)

在 org.apache.qpid.jms.example.EncryptionExample.createConnection(EncryptionExample.java:106)

在 org.apache.qpid.jms.example.EncryptionExample.runProducerExample(EncryptionExample.java:54)

在 org.apache.qpid.jms.example.EncryptionExample.main(EncryptionExample.java:48)

我认为 jndi.properties 文件中的以下代码有问题:

    connectionfactory.myFactoryLookup = amqp://localhost:5672
    connectionfactory.producerConnectionFactory = amqp://admin:admin@?brokerlist='tcp://localhost:5672?encryption_remote_trust_store='$certificates%255c/mytruststore''
    connectionfactory.consumer1ConnectionFactory = amqp://admin:admin@?brokerlist='tcp://localhost:5672?encryption_key_store='C:\OpenSSL-Win64\bin\mytruststorage.jks'&encryption_key_store_password='thanos''
    connectionfactory.consumer2ConnectionFactory = amqp://admin:admin@?brokerlist='tcp://localhost:5672?encryption_key_store='C:\OpenSSL-Win64\bin\mytruststorage.jks'&encryption_key_store_password='thanos''

这是我的解决方案资源管理器:

【问题讨论】:

  • jndi.properties 在哪里?
  • 我已通过添加解决方案资源管理器的图片来编辑帖子。
  • NullPointerException 来自您自己的代码。您有一个方法 getResourceAsStream 未实现并返回 null。你可能是想打电话给docs.oracle.com/javase/8/docs/api/java/lang/…
  • 我还注意到您正在尝试将 Qpid JMS 客户端 (qpid.apache.org/components/jms/index.html) 与消息加密功能一起使用。这行不通。我们尚未决定如何在 AMQP 1.0 中表示加密消息,并且 Qpid JMS 客户端(使用 AMQP 1.0)不提供支持。用于 AMQP 0-8..0-10 (qpid.apache.org/components/jms/amqp-0-x.html) 的旧 Qpid JMS 确实以 Qpid 供应商特定的方式支持该功能。如果您使用 Maven,如果您想使用此功能,则需要从使用 artefact qpid-jms-client 切换到 quid-client。

标签: java apache jms jndi qpid


【解决方案1】:

您遇到的第一个也是最大的问题是您尝试使用来自客户端的连接 URI 和客户端功能,而不是您已配置项目使用的客户端。您似乎正在使用Qpid JMS,这是在 Qpid 项目中开发的新 AMQP 1.0 客户端。此客户端使用与以前的 AMQP 0.x 客户端不同的 URI 语法,并且在传递这些无效 URI 时,您将从连接工厂获得异常。

您将遇到的另一个问题(在您的帖子的 cmets 中提到)是 AMQP 1.0 JMS 客户端中没有消息加密功能,因此一旦您正确定义了 URI,这将是您的下一个问题。

较新的 AMQP 1.0 JMS 客户端的文档是 here

【讨论】:

  • 我想问更多。有没有办法 system.out.println(themessagebody)?
  • 当然,从收到的消息中获取消息正文并打印出来。
  • 完美我找到了getText() 函数。不幸的是,我对 Qpid 完全陌生,我可能还有更多问题。如果我想出新的东西,我会在这里发表评论。非常感谢您的帮助!
  • 如果此问题已得到解答,请将其标记为已解决,并在出现新问题时询问新问题,这就是 SO 的工作原理。
  • 看看我的关注post
【解决方案2】:

您不能将// 用于Properties 文件中的cmets。请改用#!

见:https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html#load-java.io.Reader-

【讨论】:

  • 这是我从docs 粘贴的代码,但在stackoverflow 中它会将# 解释为粗体,这就是我更改它们的原因。
猜你喜欢
  • 1970-01-01
  • 2012-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多