I am trying to enable two way ssl authentication between Apache Ace and management agent(by following the document http://ace.apache.org/dev-doc/design/using-client-certificates.html). To achieve this , first of all i created the required certificates by following the steps mentioned below:
Step#1) Created a self-signed certificate authority using OpenSSL by excecuting the command below:
openssl req -x509 -new -config Certi/X509CA/openssl.cnf -days 365 -out Certi/X509CA/ca/new_ca.pem -keyout Certi/X509CA/ca/new_ca_pk.pem
This command created a certificate new_ca.pem and its private key new_ca_pk.pem.
Step#2) Imported the certificate new_ca.pem to keystore file named truststore by using following command
keytool -import -alias truststore -keystore truststore -file new_ca.pem
Step#3) Created certificate for the management agent, available in a Java keystore file, called keystore-ma.jks.
keytool -genkey -dname "CN=<hostIP>, OU=IT, O=<Organization Name>, ST=UP, C=IN" -validity 365 -alias keystore-ma -keypass secret -keystore keystore-ma.jks -storepass secret
Step#4) Created a CSR:
keytool -certreq -alias keystore-ma -file keystore-ma_csr.pem -keypass secret -keystore keystore-ma.jks -storepass secret
Step#5) Signed the certificate using the certificate authority created in Step 1.
openssl ca -config X509CA/openssl.cnf -days 365 -cert C:/X509CA/ca/new_ca.pem -keyfile C:/X509CA/ca/new_ca_pk.pem -in C:/X509CA/ca/keystore-ma_csr.pem -out C:/X509CA/ca/keystore-ma.pem
Step#6) Imported the certificate in a kestore file named keystore-ma
keytool -import -alias keystore-ma -keystore keystore-ma -file keystore-ma.pem
Similar steps(3-6) were followed to create and sign the cetificate or the ACE server, available in a Java keystore file, called keystore-server.
Then i updated the Platform.properties of Ace Server to include the additional properties and started Ace Server:
-Dorg.osgi.service.http.port.secure=8443
-Dorg.apache.felix.https.enable=true
-Dorg.apache.felix.https.truststore=/path/to/truststore
-Dorg.apache.felix.https.truststore.password=secret
-Dorg.apache.felix.https.keystore=/path/to/keystore-server
-Dorg.apache.felix.https.keystore.password=secret
-Dorg.apache.felix.https.clientcertificate=needs
Started ace-launcher.jar with the following command:
java -Djavax.net.ssl.trustStore=/path/to/truststore -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.keyStore=/path/to/keystore-ma -Djavax.net.ssl.keyStorePassword=secret -jar org.apache.ace.launcher-0.8.1-SNAPSHOT.jar discovery=https://<Ace Server Ip>:8443 identification=MyTarget
i tried multiple times by changing the discovery url to
1) https://<Ace Server Ip>:8080
2) http://<Ace Server Ip>:8080
3) https://<Ace Server Ip>:8443
But the target was not registered in the Ace Server. Am i using the correct URLs to connect to Ace server through HTTPS?
Also how to confirm if my Ace Server is configured to accept HTTPS traffic from the management agent?
I see you use a distinguished name (DN) with more than only a common name.
By convention, the hostname as common name is used for certificate validation. It should work if you create a certificate with CN=hostname-of-target (IP address is not sufficient).
Another hint I can give you for troubleshooting SSL errors: use -Djavax.net.debug=ssl for the server, it will spit out lots of information, but gives detailed information on what is going on and what causes the error.
Related
I am developing a REST server that runs with Jersey on Glassfish, and I want to make it run on HTTPS on localhost.
I have found many tutorials for generating a CA cert, others for generating .cer / .crt / .key / .csr / ... files, others for generating a jks keystore.
But they do not answer my (very basic) question: how to generate a self signed certificate and use it in my app that runs on Glassfish, on localhost? From scratch to the integration for a real usage, without any prerequiresite having a crt, a jks or any other file.
(For information I use Linux)
Thanks
EDIT: I have finally created a certificate with the following commands
openssl req -x509 -out localhost.crt -keyout localhost.key \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=localhost' -extensions EXT -config <( \
printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
openssl pkcs12 -export -name localhostServerCert -in localhost.crt -inkey localhost.key -out localhostP12Keystore.p12
keytool -importkeystore -destkeystore localhostKeystore.jks -srckeystore localhostP12Keystore.p12 -srcstoretype pkcs12 -alias localhostServerCert
copy localhostKeystore.jks into /glassfish/domains/domain1/config
keytool -importkeystore -srckeystore localhostKeystore.jks -destkeystore keystore.jks
And I have modified http-listener-2 in the admin console with certificate nickname localhostServerCert, but I got an error page on https://localhost:8181 (ERR_CONNECTION_REFUSED)
EDIT 2 : I think there should be a problem with the certificate, since openssl s_client -showcerts -connect localhost:8181 returns no peer certificate available, No client certificate CA names sent
COMMON GOALS
It can be useful to run with SSL locally, and I like to start with real world URLs. This can also help you to think ahead to your production deployment design, which often involves a Private PKI these days, based on a self issued Root CA.
Web and API domains can sometimes be related these days, eg if an API issues secure cookies for the web origin. So for localhost development I first define URLs such as these:
https://api.mycompany.com
https://web.mycompany.com
DEVELOPER SETUP
Then add entries such as this to my hosts file:
127.0.0.1 localhost web.mycompany.com api.mycompany.com
:1 localhost
Then, in terms of certificates, I produce these deployable files:
Certificate
Filename
Usage
Root CA
mycompany.ca.pem
The root certificate authority that is trusted by the Java runtime
Wildcard Certificate
mycompany.ssl.p12
A password protected PKCS12 file deployed with the API
My Development Certificates Repository has an example of how to issue the certs using openssl, including a bash script you can use for your own domains. Essentially this is a Private PKI for a development computer.
CONFIGURING TRUST
You then just need to trust the Root CA in the Java runtime used by Glassfish. Personally I tend to avoid JKS files where possible, since they are specific to Java, whereas PKCS12 files are a more portable concept:
sudo "$JAVA_HOME/bin/keytool" -import -alias mycompanyroot -cacerts -file ~/Desktop/mycompany.ca.pem -storepass changeit -noprompt
FURTHER DEVELOPER SETUP INFO
These resources on a portable way to manage SSL development certs are provided below, which completes the architecture work:
My Developer SSL Blog Post
My Java API uses the above certs and loads the wildcard certificate via this code, where a P12 file is used as a keystore:
System.setProperty(
"server.ssl.key-store",
configuration.getApi().getSslCertificateFileName());
System.setProperty(
"server.ssl.key-store-password",
configuration.getApi().getSslCertificatePassword());
GLASSFISH
If Glassfish based setups mean the API itself does not load the PKCS12 file, then there may be a specific task to import the PKCS12 file. Many systems provide a GUI or API option for loading a PKCS12 file into a keystore. This may result in a command like this being run, which you can do manually if needed:
keytool -importkeystore -srckeystore mycompany.ssl.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype jks -v
I have got a RapidSSL certificat and trying to install it on my Glassfish 4.0.
When I change Certificate NickName for http-listener-2 from s1as to saljex the server stops responding to https-requests.
My procedure:
openssl req -sha256 -new -key domain.key -out domain.csr
Order RapidSSL with domain.csr, copy the received certificate to file cert.txt.
keytool -import -alias saljex -keystore keystore.jks -trustcacerts -file cert.txt
Logging in to glassfish admin and change Certificate NickName for http-listener-2 from s1as to saljex.
Server stops responding to https-requests, and starts responding if I change back to s1as.
Trying to change all references in domain.xlm from s1as to saljex and now also admin-port stops responding.
I cant find any information in he log files.
Any help appreciated...
Customer support mentioned that I forgot to import my private key. I don't know exactly what I did, but the key was the key.
I have a webstart application where I want to do client authentication while connecting to the server. I have created pkcs12 certificate which I install using certmgr.exe and it works fine.
I want to do for every client that uses the application. How should I do this? If I distribute the certificate
I get a bad_certificate error. I know there isn't a problem with the certifcate because it would work if you install the certificate using the browser.
I had created the public key using
keytool -export -alias myKey -keystore abc.p12" -storetype PKCS12 -storepass mypassword -rfc -file abc.cer
then I imported this file into my server's keystore for mutual authentication using:
keytool -import -v -file abc.cer -keystore C:\apache-tomcat-7.0.26\tomcat.keystore" -storepass mypassword
after this, if I install abc.p12 certificate in certmgr, it works fine.
To be able to do it from Java, I needed a truststore. I created a truststore where I import the public key using
>keytool -import -keystore client-truststore.jks -file abc.cer
If I try to access the server using
-Djavax.net.ssl.keyStore=abc.p12
-Djavax.net.ssl.keyStorePassword=mypassword
-Djavax.net.ssl.trustStore=trustore.jks
-Djavax.net.ssl.trustStorePassword=mypassword
I'm not sure if I'm doing the right thing. Please let me know what you think.
What should I be doing? Please let me know your suggestions.
You should have imported it into your server's trust store, not its keystore.
You have to import the cert to your certs file, in the JDK is the cacerts file. After do that you have to view the cert is living on the file, and you will have do that on every client.
The thing about the trust store is that you create your own JKS file.
I am using self signed certificate for HTTPS connection to and from Axis2 server. All of these connections works fine and as desired.
There is a part in my web service which is responsible for sending emails. I am using GMail for the purpose of sending mail.
The problem is when I try to send a mail using an SSL connection I get certificate error, i.e. GMail certificate is not trusted. I had faced a similar problem with JBoss as well. For once I was able to get around this problem downloading GMail certificate and than importing it into the Keystore using Keytool utility. For a long time this had worked.
But only recently I have started to get the Old problem again. I tried to use the old technique that fixed the problem last time, but this time that did not work. (not sure why)
I reckon that GMail uses a signed certificate which out of the box should be trusted by any of the servers, let it be JBoss or Axis2. I fail to figure out what the problem actually is. Is it because of using of Self Signed certificate? Or are there any specific way of creating it so that the Signed certificates are trusted?
Thanks for the help.
To have a SSL encrypted Server/Client communication we need to Keystores and Truststore for Server & Client. Following are the steps to create them.
#Creating Server keystore and exporting a certificate
keytool -genkey -alias serverkeys -keyalg RSA -keystore server.keystore -storepass changeit -keypass changeit -dname "CN=test.com, OU=Test, O=Test, L=London, ST=London, C=UK"
keytool -export -alias serverkeys -keystore server.keystore -storepass changeit -file server.cer
#Creating Client keystore and exporting a certificate
keytool -genkey -alias clientkeys -keyalg RSA -keystore client.keystore -storepass changeit -keypass changeit -dname "CN=test.com, OU=test, O=test, L=London, ST=London, C=UK"
keytool -export -alias clientkeys -keystore client.keystore -storepass changeit-file client.cer
#Making a copy of cacerts file. These copies will be used for client/server truststore
cp /usr/java/jdk1.6.0_14/jre/lib/security/cacerts client.truststore
cp /usr/java/jdk1.6.0_14/jre/lib/security/cacerts server.truststore
#Copying server certificate to Client truststore
keytool -import -trustcacerts -v -keystore client.truststore -storepass changeit -file server.cer
#Copying Client certificate to Server truststore
keytool -import -trustcacerts -v -keystore server.truststore -storepass changeit -file client.cer
During the first few iteration I was not using cacert but directly create truststores from the certificate and that too worked well. Problems came up when we need to connect to some other services using SSL and connection could not be establised even when the service used a Signed Certificate.
For example connecting to GMail SMTP server would faile if the truststore were not created up from cacerts. Reason being even though GMail uses a signed certificate, we wold be using a truststore that would not know if the GMail certificate can be trusted. For this reason we used cacerts to create out truststore. After which we were able to connector any service that uses a Signed Certificate.
If in case we encounter a unsigned certificate we will then have to add them to the Components Truststore.
I'm trying to build a simple client/server system wich uses SSLSocket to exchange data. (JavaSE 6)
The server must have its own certificate, clients don't need one.
I started with this
http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore
To generate key for the server and a self signed certificate.
To sum it up:
Create a new keystore and self-signed certificate with corresponding public/private keys.
keytool -genkeypair -alias mytest -keyalg RSA -validity 7 -keystore /scratch/stores/server.jks
Export and examine the self-signed certificate.
keytool -export -alias mytest -keystore /scratch/stores/server.jks -rfc -file server.cer
Import the certificate into a new truststore.
keytool -import -alias mytest -file server.cer -keystore /scratch/stores/client.jks
Then in my server code I do
System.setProperty("javax.net.ssl.keyStore", "/scratch/stores/server.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "123456");
SSLServerSocketFactory sf = sslContext.getServerSocketFactory();
SSLServerSocket sslServerSocket = (SSLServerSocket)sf.createServerSocket( port );
Socket s = sslServerSocket.accept();
I am basically missing some point because I get a "javax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled." when I try to run the server.
Can it be a problem with the certificate? When using -validity in keytool the certificate gets self-signed, so it should work if I'm not wrong.
Reading the docs seems that setting the property "javax.net.ssl.keyStore" is sufficient for the SSLContext to setup correctly. Any suggestion?
I messed up things a little, complete solution is here: https://forums.oracle.com/forums/thread.jspa?threadID=1531716