Implementing 2-way SSL authentication with WebSphere MQ - ibm-mq

I use a Java client using JMS/JNDI. The connection is working when using one-way SSL authentication SSLCAUTH(OPTIONAL). The first step I did is to export the public certificate of the client:
keytool -export -keystore keystore -storepass storepass -alias CLIENT -file client.cer
Then I added this certificate to the MQ key repository.
gsk7cmd -cert -add -db keydb.kdb -pw password -label ibmwebspheremqclient -file client.cer -format binary
And I finally switched to SSLCAUTH(REQUIRED) mode.
I get the following error log. The message is pretty clear, it can't find my client certificate. I read that my client certificate should have a label ibmwebspheremq<client_user_id>. What is this user id since I am connecting via Java?
AMQ9637: Channel is lacking a certificate.

As per the Technote Specifying the userid in the SSL certificate label for an MQ client the Java and JMS clients do not find their certificate based on the label.
What is often the problem is a mis-match between the trust store and the key store. I have seen two problems fairly commonly.
The application specifies a trust store but not a keystore. This works great for anonymous (one-way) SSL but not for mutual authenticated SSL. The app must specify both key store and trust store for mutual auth.
Sometimes the app specifies a trust store file but the private certs are in the key store. Or the app specifies the same file for both trust store and the key store and the personal certs are actually in a separate trust store file.
Does either of these solve the problem? If not, please update the question with a keytool -cert -list for both the key store and the trust store and the part of the command line or code that sets up the keystore/truststore.

Related

Local setup for Elasticsearch with Xpack and Spring

I locally installed Elasticsearch with X-Pack and Kibana 8.2.2 and made it up and running. I also created a new project with Spring and Java that would connect with Elasticsearch. When running Elasticsearch for the first time it creates a certificate for the http and transport layers.
I want to use a certificate in Spring to login into Elasticsearch. Therefore I added elasticsearch-rest-client. My problem is, which certificate do I need from Elasticsearch to connect to it and be able to create e.g. role-mappings? So that I have superuser rights?
Quoting the documentation:
When Elasticsearch is configured to require client TLS authentication, for example when a PKI realm is configured, the client needs to provide a client certificate during the TLS handshake in order to authenticate. The following is an example of setting up the client for TLS authentication with a certificate and a private key that are stored in a PKCS#12 keystore.
If the client certificate and key are not available in a keystore but rather as PEM encoded files, you cannot use them directly to build an SSLContext. You must rely on external libraries to parse the PEM key into a PrivateKey instance. Alternatively, you can use external tools to build a keystore from your PEM files, as shown in the following example:
openssl pkcs12 -export -in client.crt -inkey private_key.pem -name "client" -out client.p12
How to set up PKI user authentication has a multi-page documentation and you'll be best served by using the one for your specific Elasticsearch version. The current version is available at https://www.elastic.co/guide/en/elasticsearch/reference/current/pki-realm.html but replace the current in the URL with whatever minor version you want to use (like 8.6).
PS: PKI authentication is a platinum licensed feature. But you can of course set it up with the free 30 day trial to see how it works.

java.security.ProviderException: Could not create trust object

I have Java application running on two different servers. On the 1st server while the application is trying to insert a X.509 certificate to NSS keystore it is getting the following error:
Failed to store public key certificate in keystore. Cause: Could not create trust object
java.security.ProviderException: Could not create trust object
at sun.security.pkcs11.Secmod$TrustAttributes.<init>(Secmod.java:658)
at sun.security.pkcs11.Secmod$Module.setTrust(Secmod.java:529)
at sun.security.pkcs11.P11KeyStore.engineSetEntry(P11KeyStore.java:1045)
at sun.security.pkcs11.P11KeyStore.engineSetCertificateEntry(P11KeyStore.java:516)
at java.security.KeyStore.setCertificateEntry(Unknown Source)
Using certutil to list the NSS DB entry I can see the certificate entry, but the trust flag says "CTu,Cu,Cu".
On the 2nd server, inserting a X.509 certificate to NSS keystore doesn't throw the same exception. It is working fine and using certutil I can see the certificate entry, and the trust flag says: "CT,C,C".
My questions:
Why on the 1st server inserting a X.509 certificate threw an exception?
What cause the trust flag to be different between the two certificate? The X.509 certificate is imported thru the same API.
Both servers are running Java 8u121. Thank you.

OkHttp client certificate without intermediaries

I'm trying to use okhttp to authenticate to a server.
With curl it would be done this way:
curl \
--cert certificate.cer \
--key private-key.pkcs8 \
"https://some-url"
Unfortunately, okhttp-tls appears to always expect a chain of certificates in addition to the held certificate, which isn't something I have.
heldCertificate expects the chain of certificates, in addition to the clientCertificate, contrary to the example provided in the reame:
HandshakeCertificates clientCertificates = new HandshakeCertificates.Builder()
.addTrustedCertificate(rootCertificate.certificate())
.heldCertificate(clientCertificate) // <--------------------
.build();
How can I use okhttp with a single certificate and my private key?
heldCertificates expects a chain of intermediates that may exist between the client certificate (matching the private key) and up to but not including the root CA that the server is known to trust. So this could be left out if no other certificates are required.
See https://square.github.io/okhttp/4.x/okhttp-tls/okhttp3.tls/-handshake-certificates/-builder/held-certificate/
Configure the certificate chain to use when being authenticated. The
first certificate is the held certificate, further certificates are
included in the handshake so the peer can build a trusted path to a
trusted root certificate.
The chain should include all intermediate certificates but does not
need the root certificate that we expect to be known by the remote
peer. The peer already has that certificate so transmitting it is
unnecessary.
Here are some examples for using a self-signed certificate if known to be trusted already by the server, and also for switching the key used based on the host being connected to. You will need to adapt these based on your exact setup, but they should give you a starting point to test with.
https://github.com/square/okhttp/pull/6470/files

Self-Signed Certificates in Spring-Boot

I'm trying to get a Spring-Boot server up and running, which provides some security via SSL. I followed steps 1 and 2 of this guide to get a self-signed certificate and am able to access my site via https. The application.properties looks like this:
server.port=8443
server.ssl.keyStore=classpath:keystore.p12
server.ssl.keyStorePassword=youd_want_to_know
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=hs
keystore.p12 was generated with
$ keytool -genkey -alias hs -storetype PKCS12 \
-keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
Except for the password I didn't enter anything, all fields are "Unknown".
However, the lock in the browser isn't green. The detail message says
There are issues with the site's certificate chain (net::ERR_CERT_AUTHORITY_INVALID).
The plus-side:
Secure TLS connection
The connection to this site is using a strong protocol version and cipher suite.
Secure Resources
All resources on this page are served securely.
I guess in plain text it means that the data is transported securely, but the browser isn't fully happy with the certificate in terms of it can't track the authenticity. Therefore, I understand that this isn't worthy for production (and for now it doesn't need to be).
But, is it safe and secure for me since I own the server and know that I created the self-signed certificate myself? Or are there ways to turn this into a certificate that the browser is happy with? What do I need to do to make that work and what would the Sprint-Boot configuration look like?
Thats how the browser is supposed to behave. As long as you (or rather, browsers you or your organization owns) are the only consumers of your website, you are fine. But once you want to on-board other consumers you might need to get your certificate signed by a certificate provider
In this case the communication between browser and server is still vulnerable to man-in-the-middle attack, so this not really "secure & safe"
In a Nutshell,
Using a self signed certificate is completely unsafe unless
you control every machine between you and the server
OR
you check that the keys in the certificate are what you expect them
to be.
Only advantage is; it will block passive attacks (the attacker observes the data but does not alter it in any way) regardless of whether the CA certificate was issued by a mainstream CA or not.
Take a look here https://security.stackexchange.com/a/8112

SSL certificate on Tomcat 7 configuration

I've acquired a signed certificate for use in a secure connection in Tomcat 7(.0.42). Here is what I'm given:
An x.509 certificate, primary-intermediate and secondary-intermediate x.509 certificates, an PKCS#7 chained certificate, and a private key.
I imported the certificates as specified in this guide using the x.509 certificates, then configured my SSL Connector to use the keystore, but got this error:
java.io.IOException: Alias name the_alias does not identify a key entry
I was advised to use the (also) provided PKCS#7 chained certificate, but when attempting to import it using keytool, it failed saying that it wasn't an x.509 certificate.
I understand from online lit that in the first step I was missing the "1" alias for the private key, but I have no idea how to import it. Also, I understand the PKCS#7 certificate is supposed to work fine on Tomcat, but I don't know how to import it to a keystore. I'm rather new to this, please advise!
Many thanks,
Victor.
I can not check how you implement the guide, but I do recommend to start from the self-signed certificate according to instruction here:
http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html
Ensure that keyAlias points to the alias of the server certificate in keystoreFile.
The default alias for the self signed certificate is tomcat.
<Connector port="8443"
…
keyAlias="tomcat"
…
keystoreFile="server.keystore" keystorePass="changeit"
truststoreFile="trust.keystore" truststorePass="changeit"/>
When it will work, replace the keyAlias with the alias of the signed certificate.

Resources