1

I have a question on how to connect to a remote RabbitMQ machine using java and TLS.

In java, if I use a .p12 key and the following code I can connect to the UAT machine :

{
        char[] keyPassphrase = "password".toCharArray();
        KeyStore ks = KeyStore.getInstance("PKCS12");
        ks.load(this.getClass().getClassLoader().getResourceAsStream("rmq.uat.p12"), keyPassphrase);

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, keyPassphrase);

        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509ExtendedTrustManager() {
                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
                    @Override
                    public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
                    @Override
                    public void checkClientTrusted(java.security.cert.X509Certificate[] xcs, String string, Socket socket) throws CertificateException {}
                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] xcs, String string, Socket socket) throws CertificateException {}
                    @Override
                    public void checkClientTrusted(java.security.cert.X509Certificate[] xcs, String string, SSLEngine ssle) throws CertificateException {}
                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] xcs, String string, SSLEngine ssle) throws CertificateException {}
                }
        };

        SSLContext c = SSLContext.getInstance("TLSv1.2");
        c.init(kmf.getKeyManagers(), trustAllCerts, null);

        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(rmqHost);
        factory.setPort(rmqPort);
        factory.setUsername(rmqUsername);
        factory.setPassword(rmqPassword);
        factory.setVirtualHost(vhost);
        factory.useSslProtocol(c);
        // factory.enableHostnameVerification();

        conn = factory.newConnection();
        channel = conn.createChannel();
}

On my DEV RabbitMQ machine I have a series of certificates : rmq_ca.dev.crt (cacert), rmq_cert.crt (certificate) and rmq_key.dev.key (key). And I cannot find a java code to allow me to connect using these 3 files instead of the .p12 file ...

Using nodejs I can connect using the following code :

let opts = {
    key: fs.readFileSync(path.join(appRoot, 'rmq_key.dev.key')),
    cert: fs.readFileSync(path.join(appRoot, 'rmq_cert.dev.crt')),
    ca: [fs.readFileSync(path.join(appRoot, 'rmq_ca.dev.crt'))],
    rejectUnauthorized: false
  };

...
const rmq_string = `${protocol}://${user}:${pass}@${hosts}:${port}/${vhost}`;
...

amqp.connect(rmq_string, opts, (error0, connection) => {
   ...
}

Any ideas on how to make it work on the java side ? Thanks !

R13mus
  • 752
  • 11
  • 20

1 Answers1

0

I did found a workaround - from the 3 files (rmq_key.dev.key, rmq_cert.dev.crt and rmq_ca.dev.crt) I can generate a .p12 key file using the following command

openssl pkcs12 -export -out cert.p12 -inkey rmq_key.dev.key -in rmq_cert.dev.crt -certfile rmq_ca.dev.crt

Enter Export Password: password
Verifying - Enter Export Password: password

and use this newly generate key (cert.p12) in my java program.

I saw some answers like Java p12 Generation from a existing keys which show how to the .p12 key generation programmatically directly from the java program instead of using OpenSsl but did not try it as I have a working solution.

R13mus
  • 752
  • 11
  • 20