简体   繁体   中英

How to enable SSL with client certificate for Websphere MQ client?

We are one application in a larger environment and a client for some data interface, using Websphere MQ 8.x. Our application is a Java EE application running on a WildFly 9 which uses a resource adaptor ( wmq.jmsra.rar ) which is deployed together with the EAR file in the same AS. We interact with the MQ Server in both directions. So we have on the one hand some MDBs (which are due to historical origins still in EJB 2.x format without annotations) listining to some queues and which are configured by the ejb-jar.xml deployment descriptor, containing the activation config properties destinationType, channel, queueManager, hostName, username, password . On the other hand we have a sender which lookups a queue connection factory and a queue via JNDI and creates a connection.

Now we have the requirement with a newly established MQ server to communicate via SSL and a client certificate. We got such a certificate from the server people for our machine. So my questions are:

  • What has to be done to make it work with the setup described above?
  • Is this possible purely by configuration and thus transparent for the application or has the application to specifically use SSL, present the certificate or something similar?
  • Does this conflict with any other keystore already used by some other part of the application?
  • Is some additional IBM MQ software needed to make it work? (Our client is just the RAR, no software is installed and no MQ server on our side should be established.)

Update: I went for setting the global JSSE properties for the VM as it solved my problem as a start.

It was necessary to set the following parameters:

-Djavax.net.ssl.trustStore=<location of trustStore>
-Djavax.net.ssl.keyStore=<location of keyStore>
-Djavax.net.ssl.keyStorePassword=<password>

Additionally, since I am using non-IBM VM, there was the following paramter to set:

-Dcom.ibm.mq.cfg.useIBMCipherMappings=false

Then, it was necessary to set the cipher suite property on the RAR configuration in standalone-full.xml together with the other connection parameters of my WildFly installation:

<resource-adapter id="wmq.jms.rar">
...
  <connection-definitions>
    <connection definition ...>
      <config-property name="sslCipherSuite">xxx</config-property>
...
</resource-adapter">

And finally, the MDBs listining on the queues also had to be configured to use the cipher suite, so in my case I had to add that in the ejb-jar.xml by adding for each MDB:

<activation-config-property>
  <activation-config-property-name>sslCipherSuite</activation-config-property-name>
  <activation-config-property-value>xxx</activation-config-property-value>
<activation-config-property>

OP stated in the comments that they use OpenJDK 8 and are using the IBM MQ v9.0.0.1 resource adapter, both of the following known problems are fixed in that release, but putting this information here for the benefit of others who may not yet be at a release where these are fixed:

  • APAR IV66840 : TLS cipherspecs in non-IBM JREs were not supported until 8.0.0.2.

  • APAR IT10837 : WildFly 9 may hit another issue if using a non-IBM JRE in finding the KeyStore that contains the client cert, this is fixed in 8.0.0.5.


The resource adapter includes the MQ functionality to support TLS but uses the underlying JSSE for the actual encryption.

Based on RFC 5246 it suggests that the TLS Client should only return a cert that is suitable based on the the server sending " A list of the distinguished names [X501] of acceptable certificate_authorities, represented in DER-encoded format. ", this would mean that if the certs in your keyStore for the different uses (ex: existing non-MQ certs and MQ certs) are not signed by the same CA chain, and the various TLS servers you connect to do not accept certs from the CA of other certs in your key store (ex: existing non-MQ certs and MQ certs) then JSSE will return the appropriate cert to each.

For example if existing non-MQ certs are signed by a Internal CA and the MQ cert is signed by another company's CA, it is highly unlikely that the MQ company would trust your internal CA certs, conversely it is unlikely that your other non-MQ TLS servers you connect to would trust the other company's CA. Since JSSE would return only a cert that was trusted by the remote server they should not impact each other. You would just need to add the MQ cert to your existing key store.

Quotes from the relevant sections of RFC 5246 are at the bottom of this post.


@a_cornish_pasty answer to your question " Use specific keystore for JMS " is also an alternative as it would allow you to specify a separate key store from what the rest of Wildfly uses, this key store could have ONLY the MQ cert, so no chance of causing an issue with the existing key store and certs.


RFC 5246 Section 7.4.4 states the following:

7.4.4. Certificate Request

When this message will be sent:

A non-anonymous server can optionally request a certificate from the client , if appropriate for the selected cipher suite. This message, if sent, will immediately follow the ServerKeyExchange message (if it is sent; otherwise, this message follows the server's Certificate message).

It then goes on to state:

certificate_authorities

A list of the distinguished names [X501] of acceptable certificate_authorities , represented in DER-encoded format. These distinguished names may specify a desired distinguished name for a root CA or for a subordinate CA; thus, this message can be used to describe known roots as well as a desired authorization space. If the certificate_authorities list is empty, then the client MAY send any certificate of the appropriate ClientCertificateType, unless there is some external arrangement to the contrary.

RFC 5246 Section 7.4.6 states the following:

7.4.6. Client Certificate

When this message will be sent:

This is the first message the client can send after receiving a ServerHelloDone message. This message is only sent if the server requests a certificate. If no suitable certificate is available, the client MUST send a certificate message containing no certificates. That is, the certificate_list structure has a length of zero. If the client does not send any certificates, the server MAY at its discretion either continue the handshake without client authentication, or respond with a fatal handshake_failure alert. Also, if some aspect of the certificate chain was unacceptable (eg, it was not signed by a known, trusted CA), the server MAY at its discretion either continue the handshake (considering the client unauthenticated) or send a fatal alert.

It then goes on to state:

  • If the certificate_authorities list in the certificate request message was non-empty, one of the certificates in the certificate chain SHOULD be issued by one of the listed CAs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM