How to make my server trust with a certificate? - java

On my java application, that runs on Tomcat in a RedHat linux machine, I need to send a request to an API that uses ssl trust certificate. Our partners have already sent us two files that should be used to trust them: wse-tst_partner_com.crt and DigiCertCA.crt.
Our partners have sent these instructions: https://www.digicert.com/csr-ssl-installation/apache-openssl.htm#ssl_certificate_install
However, I'm stuck on step 2, since I didn't find an httpd.conf file, neither apache2.conf file. I wonder if these are not applicable to Tomcat (they didn't actually know what we have before creating the API and their security stuff).
I've also tried to look for installing trust certificates for Tomcat, but the instructions I've found were only to create a new certificate with keytool - I don't want to create a new certificate, I need to "trust" the ones our partners already created.
I've also found this question on serverfault. However, I don't have any .pem files, and I don't want to create new files - I just want to use the ones I mentioned on the beginning of this post.
I'm a noob in this subject - I don't think this should be a complicated task... Should I add something to my server.xml file? Or, maybe I'm looking for the conf files in the wrong place?

httpd.conf and apache2.conf are apache files not tomcat.
They assumed you were using apache instead of tomcat.
Either put an apache in front of tomcat and use that guide or create a keystore with keytool (A keystore is "like a box" containing the certificates) and add the certificates you were provided inside, you will need to add the intermediate and the root as well. And then configure tomcat (listeners, connectors) to use that keystore.
Follow the steps from this guide instead https://www.digicert.com/csr-ssl-installation/tomcat-keytool.htm but ignore the creation of certificate as the certificates are already provided. Make sure you have the key as well, otherwise you'll have to create the CSR in the server and provide that to whoever signs the certificates (your partner I guess) and they will get back to you with new certificates. Incorporate the certs to the keystore as suggested.

Related

Should I use either cacerts or local trustore but not both?

We have a local truststore.jks we use for our app. We pass this to the app using VM Options like so:
-Djavax.net.ssl.trustStore=<<PATH TO TRUSTSOTRE.JKS>>
If we are already using this truststore.jks is there any good reason to import certificates into the cacerts file of our jdk?
Couldn't we just import these certs into out existing truststore.jks?
There is no right or wrong here, and the decision depend on your application the operation and approach to managing security setup.
Personally I would always prefer to use a custom trust store (as you are already doing), only containing the trust path for the endpoints that are required for your app.
This way you would only have to maintain trust for the endpoint(s) you are using.
However, if the app connects to many TLS endpoints using certificates from different CA providers, a trust store based on cacerts could make maintenance easier if/when endpoints changes issuer.
In that case I would advise to not change the cacerts file in the JRE, but base a custom trust store file on the cacerts file for use by the application.

JBoss/Java and SSL

Hi I'm a bit lost and hope you'll get me out of here. I'll try to be as clear as possible since I don't really understand/know how I should use certificates.
I've got an application that is supposed to communicate with another one using webservices and SSL. We both asked our main "Certificate Authority" to get certificates.
They sent us 4 files and a password for the .P12 file:
.csr, .cer, .key, .P12
Here is what I did :
* Configure JBoss to use SSL on 8443 and used the P12 file as the keystore
To test this I did a small Java class that call a webservices on this server, using :
props.setProperty("javax.net.ssl.trustStore", "/.../.../certif.p12");
props.setProperty("javax.net.ssl.trustStorePassword", "XXXXXXXXX");
props.setProperty("javax.net.ssl.trustStoreType", "PKCS12");
The connection works, but I think I'm missing something as I did not use the other files.
If I send my .P12 file and the password to the application that is supposed to call my Webservices will it be ok/enough ?
Edit :
I forgot to mention that I should call a Webservice on the other application too, so it should be the other way around, do I only need a .P12 and pass ?
I've read a lot of thing about public key, private key, keytool but it's a bit messy in my head right now.
Thanks for any information !
They sent us 4 files and a password for the .P12 file: .csr, .cer,
.key, .P12
Ideally, you should have generated the private key (in .key) and CSR (in .csr) yourself and the CA should have come back with the certificate (typically in .cer) based on the CSR, which you would have assembled together to build your PKCS#12 file (.p12).
At this stage, you can discard the CSR. The PKCS#12 file should now contain the private key, its associated certificate and possibly the certificate chain attached. You could extract the .key and .cer files from that .p12 file later again. I guess you were given all these files because of the way they have been generated (using intermediate files), or for convenience, not to have to convert them yourself.
The Java terminology isn't ideal, but keystore and truststore are two entities of type keystore, but with a different purpose. The difference between the KeyManager and TrustManager (and thus between javax.net.ssl.keyStore and javax.net.ssl.trustStore) is as follows (quoted from the JSSE ref guide):
TrustManager: Determines whether the remote authentication credentials (and thus the connection) should be trusted.
KeyManager: Determines which authentication credentials to send to the remote host.
The javax.net.ssl.trustStore* properties are one way of configuring the TrustManager. The javax.net.ssl.keyStore* properties are one way of configuring the KeyManager.
Typically, there is no need for private key material in a trust store (unless you also use the same as a keystore). It's often better to use a separate truststore, which you'd be able to copy freely across machine, without worrying about leaking private key material.
What would make sense would be to build a new keystore (JKS) that you would use as a truststore, using the CA certificates (not sure if you've been provided with them).
You're not doing mutual authentication by setting the truststore only (there are no default values for the keystore, so they need to specify these parameters explicitly). If you want to use your client-certificate to connect to a remote party, you need to set it in the keystore (for example, using the javax.net.ssl.keyStore* properties in the same way you've done it for the trust store).
You could point both the keystore and truststore to the same .p12 file. The side effect is that other connections made by your service to other places (e.g https://www.google.com) would not be trusted, since it wouldn't contain the CA for those. That's why it might be better to create a separate "truststore keystore" (JKS might be easier) for the CA certificates. You could make a copy of the default cacerts (in the JRE directory), import your CA's certificate into it and use that.
I've got an application that is supposed to communicate with another
one using webservices and SSL.
Ok, stop here. Communicate how? I mean is it only server authentication i.e. your client application will authenticate the web service or mutual authentication and the web service will also request your applications certificate?
This is important as the files you present by the names seem to suggest the latter i.e. that mutual authentication is expected while your code you show is only setting SSL library for server authentication.
Since you are not providing context here I would say that:
.key has your private key
.p12 has your private key along with your signed certificate or perhaps the CA's root certificate (?)
cer could have your signed certificate or perhaps the root's CA
signing certificate that is considered as trusted in the domain and
has probably also signed the web service you want to communicate with
certificate (well that is a possibility/guess here since you don't
say much)
csr is your certificate signing request
I did a small Java class that call a webservices on this server, using
What you do in the code is setting the p12 as the truststore.
If you say this works then there is no mutual authentication only server side authentication and you are authenticating the web service using whatever is in the p12.
In this case the rest are not needed for communication.It is for you to keep especially the key file since this could be your private key and if you lose/someone steals this then your private certificate is useless/compromised.
I am not sure what your requirements on security are here, but it seems to me that you should probably look into it more.
Even for this question I just tried to do an educated guess based on the file names.....
I hope this puts you in some track to read.

Is it a bad practice to use Java standard keystore

We had been using java standard keystore ($JAVA_HOME/jre/lib/security/cacerts) as the trusted store for tomcat. And that tomcat server would communicate with some other server. A recent OS(AIX) upgrade apparently over-wrote the file at $JAVA_HOME/jre/lib/security/cacerts and that resulted in lost certificates and lot of issues with application hosted in tomcat.
Looking at this is it a bad practice to relay up on $JAVA_HOME/jre/lib/security/cacerts ?
What are the alternate (better|standard) ways to tackle this scenario?
It's not a bad practice if you have a build process that will repeat the imports.
Not sure, but assuming your assumptions are correct, caution where you put your keystore. I would strongly suggest it is placed inside Apache folder.
By default in Websphere the keystore works this way, since it brings it's own JVM :)
In terms of what is in the cacerts file, it's not necessarily worse practice than relying on the default CA certificates installed in your OS or your browser, but that doesn't mean it's great.
Sun/Oracle have a little "important note" somewhere in the middle of the JSSE Reference Guide about this:
IMPORTANT NOTE: The JDK ships with a limited number of trusted root
certificates in the /lib/security/cacerts file. As
documented in keytool, it is your responsibility to maintain (that is,
add/remove) the certificates contained in this file if you use this
file as a truststore.
Depending on the certificate configuration of the servers you contact,
you may need to add additional root certificate(s). Obtain the needed
specific root certificate(s) from the appropriate vendor.
In terms of configuration, for specific applications where I've had to install "local" CA certificates, I find it more stable to use a local trust store (for example, specified with javax.net.ssl.trustStore).
Yes it is a bad practice to do that.
The best practice is to have to limit your trusted certificates as much as needed.
So you should have used you own keystore with only the certificates trusted by your application.
The AIX upgrade is a patch. Any patch must not delete / overwrite user data. I would suggest that users affected by this kind of data loss ask IBM to fix the patch procedure. In comparison, a patch of the httpd server does not overwrite / delete the configuration even though it is in the program directory.

Accessing SSL Private Key From a Servlet

I'm running Apache Tomcat locally and have installed a self signed certificate using OpenSSL. I also have a servlet running.
What I want to do is the following:
The servlet takes in POST parameters and will echo back the parameters signed using the PrivateKey of the server. That is, treat the input parameter as an integer and raise it to the power of the private key.
The problem: Is it even possible to access the server's PrivateKey from the servlet? If deployed on some other hosting, it's probably not possible to access it directly. So is there any way that I can request that the server 'sign' some piece of data with its Private key?
Thanks in advance.
If I were writing a weberver I'd go to great lengths to prevent code from reading from the certificate store - I certainly wouldn't provide an API call for it!
Usually the cert is stored as a file on the webserver's filesystem (not always) but for a site with any serious security on it, this would be encrypted and require a passphrase to decrypt. Since you are using a self-signed certificate its probably not encrypted - just import the cert from the file into the keystore.
This depends on the way the container is configured. In the general case, the SSL configuration of the container will not be accessible by a servlet it contains. For example, in Apache Tomcat, that connector's SSL configuration can be completely independent of the settings accessible by a servlet. (In addition, SSL may be handled by APR or an Apache Httpd front-end, for example, which won't have much to do with the Java keystore configuration).
You would probably be able to gain access to the keystore if they are configured using the javax.net.ssl.* properties. However, that's not necessarily the way the SSLContext of the server connector is configured from. It's not generally a good idea to pass those parameters on the command line either in a production environment.
What you may be able to do is to load the keystore used by the container, from your servlet, but you'd have to know where it is, in advance. In addition, I would suppose that a hosting service would run Tomcat with a security manager turned on, which may prevent you from doing this.
Note that you could use your own keystore, shipped within your webapp (it can even be loaded from the classpath as a resource stream). Whether this keystore will contain the same private key as the one use by the server's SSL layer is up to the server's administrators (if they let you have it).
If you use a Java keystore you can access it from your servlet, as long as it knows the keystore location and password.
Servlet can access any data on your machine including keys. The only situation can be when Apache and Tomcat are running from different user names and keys are locked to be accessed only by Apache user name. You can do a trick in this case as su a process under Apache user name and read the file.

How to use PEM file to create a SSL socket in Java?

See related question.
I have a PEM file provided to me and was told that it will be needed in establishing a SSL socket that connects to a c++ server for some API calls. Does anyone know how I can read in the PEM file and connect? I was also given the parapharse password.
It sounds like the PEM file is a client cert for you to use to login to the server. If it is the client cert, and it sounds like it is, you will likely need a ca cert file also to use in validating the servers certificate in order to establish a connection.
The CA certs need to go into a truststore and your client certs need to go into a keystore. In Java, both of these will be JKS (although it has limited support for PKCS12.) There are default keystore/truststore locations for the JRE as well as for each user. You can also specify external locations for these files in your code, as in the examples below. The commons-ssl library seems to be able to support PEM directly, without the need for JKS, but I haven't used it.
The default passphrase for these keystores in Java is "changeit" without the quotes.
This page shows you have to read the PEM into your keystore/truststore. Here is another example.
Once you have your truststore and keystore set up properly, you need to pass the following JSSE system properties to your JVM:
javax.net.ssl.keyStore
javax.net.ssl.keyStoreType
javax.net.ssl.keyStorePassword
javax.net.ssl.trustStore
javax.net.ssl.trustStoreType
javax.net.ssl.trustStorePassword
You may specify them as -D parameters to the JRE or, as in the examples below, programatically.
Once you finish that, heres a commons-ssl example of creating a socket. Also, heres the Java api for SSLSocket. Heres also an example that doesn't use any apache commons.
You need a library that handles SSL. As John Ellinwood noted, some frameworks (such as Java 2 SE) offers these built-in, for others you'd need to use 3rd party libraries.
C developers often use openssl directly, but it can't be said to be easy and when using C++ there are several "gotchas" that are easy to fall into.
I suggest you use a C++ network library with support for SSL, such as QT's network library, or Poco NetSSL. See here for some tutorial documentation and here for the API documentation - you probably want to take a look at initializeClient which takes a PEM file directly.

Categories