I generated a private key pair using KeyStore Explorer that was signed by Sectigo [formerly Comodo] yesterday. The goal is to employ this in an SSL mutual authentication scenario. I work with iWay, a java application, that will post messages to SAP's CPI, a service on cloud. The service on CPI has client authentication enabled [specific to the resource, not at host:port]. I have created a keystore with our private key and a truststore with some public certs in it. In response to a failed communication, I've enabled SSL debug on the application and here are my findings:
*** ServerHelloDone
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>
***
This is reported at a stage when server cert was validated and accepted. In order to ensure whether or not the key in question took effect, I verified the logs and noticed the following, which assures that, it did [key name changed for security reasons]:
found key for : self_***.com_priv
I also verified that SAP accepts certificates when signed by valid CAs in the log that looked like this:
Cert Authorities:
...
<CN=USERTrust RSA Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US>
...
This is how the signed cert look like, when opened on Windows:
I have the following questions:
1) The chain is displayed in the certificate when opened on Windows but not on KeyStore Explorer. Anyone know why?
2) The USERTrust root CA appears to be imported into SAP's trust store based on the log given above. In the picture above, the root cert, although, reported as Sectigo, which happens to be a friendly name, has its issuer name conforming to the one imported onto SAP's trust store:
I hence am not sure why java will not render this cert to SAP during TLS handshake. Any thoughts please?
3) The intermediate certificate has a property named Authority Information Access, in which, a link to its root is present. The properties of this root is entirely different from that of the root I see in picture at item 2 above. Does this matter at all?
Any help will be appreciated. Thanks.
Problem solved. It was due to the way, I imported the CA Reply into my private key. I imported only the signed entity certificate while it looks like I must had imported in PEM format. Thanks to Bruno who have explained the resolution HERE. I am relieved!
Related
Let me give a little bit of background before I ask the question, so that we have clarity on the problem itself. We need to support one way SSL with Elasticsearch (v5.2.x), using searchguard ssl. We have a list of procedures for developers (not for production), which takes care of generating a self signed SSL cert. Here we've one root (locally created) and the actual cert. If we import the keystore (containing the private key and signed cert) and the truststore (containing the root cert) everything works fine.
But couple of days back, we got one request from a client. There, in production we need to support SSL. So, we followed the steps below:
with our script, we generated the private key, imported it into the keystore, and also generated the csr.
We gave the client the csr. He got it signed by a proper CA, and gave us back the cert.
Now the chain of trust is of length 3, for the cert given. So, there's a root CA, which signed the cert (issuer1), which signed the cert (issuer2), which in turn signed the actual csr.
For importing the actual cert to the keystore, we imported all the three parents, and then imported the actual cert.
Then we removed all the parent certs from keystore. So, now the keystore has only the private key and the actual cert.
We imported all the three parent certs into the truststore.
Now, if we start Elasticsearch, the following error is thrown: [ERROR][c.f.s.s.t.SearchGuardSSLNettyTransport] [uyyIg3i] SSL Problem Received fatal alert: certificate_unknown
javax.net.ssl.SSLException: Received fatal alert: certificate_unknown
Funny thing is, the exact procedure works, if we have only the root ca, signing the actual csr. Any help is appreciated for figuring out the root cause of this issue, as I'm sort of out of ideas now.
After couple of tiresome debugging sessions, we found out the CN-name and the actual host-name to be different. After making both of them same, we got it working.
I'm using Java Web Start (JWS) to deploy and run my JavaFX application. The jnlp element of my jnlp file is defined as follows:
<jnlp spec="1.0+" xmlns:jfx="http://javafx.com" codebase="http://www.example.com/software" href="MyJnlp.jnlp">
My application successfully launches using the configuration above. I'm now trying to adjust the jnlp file such that the jars are downloaded over SSL. I purchased and installed an SSL certificate for my domain. I've confirmed that the certificate was successfully installed by pointing my browser to https://www.example.com/software/MyJar.jar and verifying that the jar is downloaded.
I updated the jnlpelement of my jnlp file as follows:
<jnlp spec="1.0+" xmlns:jfx="http://javafx.com" codebase="https://www.example.com/software" href="MyJnlp.jnlp">
When I launch the application by double clicking the jnlp file I get a warning from Java stating that "The connection to this website is untrusted" and clicking on "More Information" I see a message stating that "The Certificate Authority that issued the certificate is not trusted" (warnings pictured here)
My SSL certificate relies on a chain of SSL certificates to link it to a root certificate. I opened the Java console and verified that my root certificate is present under the System section of the Secure Site CA "Certificate Type" tab (pictured here).
As a test, I then tried importing my site's SSL certificate to the User section of the Secure Site "Certificate Type" tab. After my site's SSL certificate was imported I no longer received the warning.
Based on this test, it seems to me that Java may not be reading/able to read the intermediate certificates in the certificate chain that links my certificate to a root certificate.
I'd like my users to be able to launch the JWS application over https without importing my site's certificate or being prompted with a warning. Can anyone help?
Upon further investigation, it appears that my original suppositions surrounding the source of the failure may have been incorrect. I used openssl to view the certificate and certificate chain presented by the server hosting my Java Web Start codebase (I'm using openshift). The SSL data showed that although the SSL certificate for my custom domain was being presented, the certificate chain corresponded to RedHat's default SSL configuration (which obviously does not validate my custom domain's certificate).
My-MacBook-Pro:~ username$ openssl s_client -connect www.example.com:443
CONNECTED(00000003)
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=North Carolina/L=Raleigh/O=Red Hat Inc./CN=*.rhcloud.com
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
***CERTIFICATE FOR MY CUSTOM DOMAIN***
-----END CERTIFICATE-----
Since the server was presenting the certificate chain for openshift's default SSL support I decided to change the codebase attribute of my jnlp file to point to Redhat's provided domain which resolved the "Untrusted Connection" error.
I'm satisfied with this outcome. However, to use my custom domain I believe the right course of action would be to follow-up with Redhat to determine why the pem file which included my certificate chain is not being presented when accessing the server using my custom domain name.
I've a task to write a communicator with PKI. I think about implementation (in Java)of X.509 certificate - I mean SSL/TLS to allow for data/message confidentiality, and message authentication codes for message integrity. All about these I've read in some literature and it's all theoretical. I'm not sure if I think properly. Could anyone, who good understand idea of PKI, give me any advice (for example website where it's good explanation of implementation PKI)?
As ntoskrnl commented, this is hard to do exactly right, even by the experts.
Here is a basic high-level look at the PKI you will need for an SSL connection:
A CA root key and corresponding self-signed certificate.
An intermediate CA key and certificate signed by the CA root key (this
is optional).
A server identity key and certificate signed by either
the intermediate CA or the CA root.
A client identity key and certificate signed by some CA that the server trusts. For your
academic work, you may want this CA to be the same as the one you created. The client identity is only needed if you want to have 2-way (mutual) SSL, where the server authenticates the client.
A web service that is running on something like Tomcat that can be configured for SSL. On the server side, the identity would point to the server key certificate. For 2-way SSL, there would also be a list or keystore of trusted CA certs on the server. Unless a client's certificate was signed by one of those trusted CAs, the server would not allow the client to connect.
On the client side, you would also need a list or keystore of trusted CA certs, and the server's certificate would have to be signed by one of those CAs. The client ID key and certificate and trust keystore would be used by Java when establishing an SSL connection. If you search Stack Overflow, you should find plenty of Java SSL connection examples.
To create the PKI, OpenSSL is a good tool to use. Here is one helpful website:
https://pki-tutorial.readthedocs.org/en/latest/simple/index.html
For a key and its corresponding certificate, you first create a private key, then create a certificate signing request (CSR). The CSR is then signed by a CA key, and becomes a certificate. The certificate contains the public key that corresponds to the private key used to create the CSR.
For MAC, there's a Java example of HMAC here: HMAC-SHA1: How to do it properly in Java?
I am experiencing an issue when calling web service in my java project. The web service client is running in an java ee application deployed in WebSphere 7. The SSL certificate chain is having the root certificate of Go Daddy Class 2 Certificate Authority. and I do see it in the cacerts file under the WebsPhere JVM folder, but I am keeping getting untrusted certificate error:
java.security.cert.CertPathValidatorException: The certificate issued by OU=Go Daddy Class 2 Certification Authority, O="The Go Daddy Group, Inc.", C=US is not trusted; internal cause is:
java.security.cert.CertPathValidatorException: Certificate chaining error
Cant figure out why getting this error, and how I can resolve this issue. Please help me.
The web service is running in Server A, The client works well when I run it on my machine, the cacerts on my machine includes that root certificate.
When the client get deployed with an web application onto Server A, it doesn't work. We checked the cacerts file, it does include the go daddy root certificate.
When the client and webservice get deployed onto some other envs running with VeriSign certificate chain, it works as well.
Thanks
In my opinion, the CA root public key should be added to your trust store as you are using your server it as a webservice client and not a webservice server.
On your admin console, you should have:
Security->SSL certificate and key management->Key stores and certificates-> NodeDefaultTrustStore-> Signer certificates
Chaining error
You haven't imported the chain correctly, or there is something wrong with it. I use GoDaddy certificates and I don't get chaining errors, so it is more likely the former.
I'm trying to set up a test environment for our application that uses X.509 client authentication over HTTPS in Tomcat 6.0. The servlet code is expecting to get a certificate chain as an array of X509Certificate objects using the javax.servlet.request.X509Certificate of the servlet request. However, this array only contains a single item (the client certificate), where I'm expecting it to have two (the client certificate and the root CA certificate that signed it).
Here's what I've done so far:
Generate a self-signed CA certificate using openssl.
Import the CA certificate as a trusted root certificate into a newly create Java keystore.
Configure the Tomcat HTTPS connector to require client authentication using the keystore created in step 2 as the truststore:
clientAuth="true"
truststoreFile="<path_to_truststore>"
Generate a new client certificate using openssl and sign it with the CA certificate.
Start Tomcat.
Install the client certificate in Chrome and navigate to my server's homepage. Stepping through the code in debug, I can see that the array returned as the javax.servlet.request.X509Certificate attribute only has the client certificate.
I know that Tomcat is picking up the root CA certificate from the truststore because when I delete it from the truststore, I get an SSL connection error. It's just not making it into the servlet request like the documentation says it should. Am I missing any additional configuration here? Perhaps Tomcat (or Java or JSSE) is expecting some additional X509 V3 extensions or something?
Any help is appreciated!
EDIT
Looks like my setup is legit, and this falls into the category of unusual but expected behavior due to a simplified test environment. In an enterprise scenario it's unlikely that the root certificate authority is going to be directly signing client certificates for individual users. Clearly when this code was written and tested, there was at least one intermediate CA involved in the trust chain.
What your are seeing is what is expected: Chrome is not sending the CA.
During the TSL Handshake when authenticating the client, the server will send a list of acceptable CAs as part of its CertificateRequest Message (RFC), the browser will then present a Certificate signed by one of these CAs.
ADD
btw, a great way of debugging an SSL connection client side is to use the fantastic openssl tools
openssl s_client -connect ssl.server.com:443
or for SSLV3 only servers
openssl s_client -connect ssl.server.com:443 -ssl3
This will print (among other things) the list of acceptable CAs.
To debug the server side add this to the JVM command line -Djavax.net.debug=ssl
The identity keystore should contain the cert signed by the CA ; not the self-signed cert. The CA root should be in the truststore.
Also, what is the purpose of step 4 ?