Client authentication in server Tomcat - java

i want to configure SSL for mutual authentication.
I work with eclipse + tomcat 8.
I do this passages:
I created private keys in this way:
openssl genrsa -des3 -out client_key.pem 2048
openssl genrsa -des3 -out server_key.pem 2048
I created self-signed certificates:
openssl req -new -x509 -key client_key.pem -out client.pem -days 365 -config <path to>\openssl.cnf
openssl req -new -x509 -key server_key.pem -out server.pem -days 365 -config <path to>\openssl.cnf
I created truststore and import certificates:
keytool –importcert -trustcacerts –keystore clienttruststore.jks –storetype jks –storepass <truststore_password> -file <path-to-file>\server.pem
keytool –importcert -trustcacerts –keystore servertruststore.jks –storetype jks –storepass <server_truststore_password> -file <path-to-file>\client.pem
I combined the certificate and the private key for the server and client respectively:
openssl pkcs12 –export –inkey client_key.pem –in client.pem –out client.p12
openssl pkcs12 –export –inkey server_key.pem –in server.pem –out server.p12
and finally i converted the keystore in pkcs12 format:
keytool –importkeystore –srckeystore client.p12 –srcstoretype pkcs12 –destkeystore client.jks –deststoretype jks
keytool –importkeystore –srckeystore server.p12 –srcstoretype pkcs12 –destkeystore server.jks –deststoretype jks
After this, i configured configure SSL/TLS support on Tomcat. So, i configured server.xml in Servers folder and setup the connector in this way:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="path\to\server.jks" keystorePass="*******" keystoreType="JKS"
truststoreFile="path\to\servertruststore.jks" truststorePass="********" truststoreType="JKS" />
Finally i clean and build the project.
I created a Dynamic Web Project in Eclipse that called "myproject". It works well.
The problem is that when myproject runs on server at URL https://localhost:8443/myproject
Google Chrome shows the red triangle (This page is insecure (broken HTTPS)).
What's wrong?
Where do i put client.jks e clienttruststore.jks in my project?
This picture shows problem:

Your certificates are self signed, meaning they are not signed by CA, meaning Chrome cannot trust them unless you approve them manually.
When generating certificate did you provide CN? It must match the hostname that you are using (in your case it's localhost), if CN doesn't match, Chrome will not allow SSL unless you approve it manually.
You said you want the mutual authentication, but you configured clientAuth="false" It should be true. As for the keystore, you supposed to use the same keystore for the certificates, therefore when client connects with it's certificate, tomcat will validate that corresponding certificate is located in the keystore.
Hope it helps.

Related

Import private key and certificates into Java keystore

I have been provided with:
A private key (-----BEGIN RSA PRIVATE KEY-----)
Intermediate CA cert (-----BEGIN CERTIFICATE-----)
Root CA cert (-----BEGIN CERTIFICATE-----)
SSL connectivity exists and I have proven this successfully using curl;
curl -vv https://thirdparty.service.com --key private.pem --cert cert.crt
However, I wish to establish this SSL connection using Java. Given this, I know I need to import these certificates and key into my Java keystore.
I initially imported the Intermediate and Root CA certs only into my Java keystore but I could not establish a successful SSL connection to the third party service. Based on my curl command, I realised that I need to somehow import the private key into the Java keystore.
I have tried many openssl/keytool commands and this is the current combination/command I have running. I still cannot establish an SSL connection using Java.
cat cert.crt cachain.crt > import.pem
echo "pazzword" > pazzword.txt
openssl pkcs12 -export -in import.pem -inkey privkey.pem -name my_bundle -passout file:pazzword.txt > server.p12
${JAVA_HOME}/bin/keytool -importkeystore -srckeystore server.p12 -destkeystore ${JAVA_HOME}/jre/lib/security/cacerts -srcstoretype pkcs12 -srcstorepass pazzword -deststorepass changeit
Versions:
openjdk version "1.8.0_345"
OpenSSL 3.0.7 1 Nov 2022 (Library: OpenSSL 3.0.7 1 Nov 2022)
Can someone please help clarify what I should be doing with the certs and key I have above?
A successful SSL connection using my Java

Use certificate for HTTPS request in Java

I want to call some web services through an HTTPS connection in Java. The certificate authority gave me a PKCS12 file but I get a
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
due to
javax.net.ssl.SSLHandshakeException
Here is the code I am executing :
System.setProperty("javax.net.ssl.keyStoreType", "JKS");
System.setProperty("javax.net.ssl.keyStore", "path/toto2.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "pwd");
System.setProperty("javax.net.ssl.trustStoreType", "JKS");
System.setProperty("javax.net.ssl.trustStore", "path/toto2.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "pwd");
System.setProperty("proxySet","true") ;
System.setProperty("https.proxyHost", "XXX") ;
System.setProperty("https.proxyPort", "XXX") ;
I first tried to give the PKCS12 file, then the JKS but I had the same error.
I tried another solution, with curl. So I extracted certificates from the PKCS12 and the requests successed.
Here are the commands that I used to extract the different files from the P12 :
openssl pkcs12 -in file.p12 -nocerts -nodes -out clientcert.key
openssl pkcs12 -in file.p12 -clcerts -nokeys -out clientcert.cer
openssl pkcs12 -in file.p12 -cacerts -nokeys -chain -out cacerts.cer
Am I wrong with the way I use those files in Java ?
PKCS12 normally contains a privatekey and cert (chain) combination, and is used to authenticate your system i.e. the client, which is done with the javax.net.ssl.keyStore* properties. You should specify type PKCS12, although some Java8 versions (only!) can read PKCS12 when you specify JKS.
It typically does NOT authenticate the server(s), which is what javax.net.ssl.trustStore* is for, so don't use it there. Depending on the server(s?), you may or may not need a custom truststore different from the P12 and also different from Java's default.
Look at the cert chain used by the server with a browser or other tool like curl or keytool -printcert -sslserver host[:port]
and determine whether it uses a public root CA like Verisign-now-Symantec-now-Digicert or GoDaddy, which will already be in Java's default truststore, or a 'private' CA or even a self-signed cert, in which case you should either add that cert to the default truststore or if you can't or don't want to modify your JVM put that cert in a keystore file you use as the truststore.
PS: the ValidatorException causes the SSLHandshakeException not the reverse.

SSL websockets proxy via nginx proxy with client auth

I'm having trouble setting up a reverse proxy through nginx to a websocket application with client certificate authentication; so far I've gotten the server SSL cert to work no problem. Here are my steps so far for the client auth:
Create the client cert:
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
openssl genrsa -out client.key 1024
openssl req -new -key client.key -out client.csr
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey \
ca.key -set_serial 01 -out client.crt
Configure nginx:
daemon off;
events {
worker_connections 4096;
}
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443;
ssl on;
server_name rserve;
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
# ssl_client_certificate /etc/nginx/certs/ca.crt;
# ssl_verify_client on;
location / {
proxy_pass http://localhost:8081;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
}
If I enable the ssl client stuff things stop working. On the client I'm using a jetty implementation (java), I import the client cert into a keystore with this line:
keytool -import -trustcacerts -keystore keystore.jks \
-storepass changeit -noprompt -alias client -file client.crt
This procedure worked for a selfsigned server cert. The failure is reported on the client as a failure to switch protocols, this is in line with my previous failures on behalf of the SSL handshake - the proxied application is websocket only.
You created the private key outside of the keystore and have now imported just the certificate. The client application needs access to both the private and public parts.
Either import the private key or generate the certificate signing request using keytool rather than openssl.

COMODO SSL certificate on Jboss7

I registered a domain and would like to set up SSL encryption for it. My domain provider offered me to get a SSL certificate from COMODO. I generated a key and a csr file using openSSL:
openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out server.csr
The command produced a private key, myserver.key and the csr file. I uploaded the content of the csr to comodo, and after verification, they sent me the following files:
Root CA Certificate - AddTrustExternalCARoot.crt
Intermediate CA Certificate - COMODORSAAddTrustCA.crt
Intermediate CA Certificate - COMODORSADomainValidationSecureServerCA.crt
Your PositiveSSL Certificate - mydomain.crt
I'm lost on where to go from here. I followed these instructions:
https://support.comodo.com/index.php?/Default/Knowledgebase/Article/View/638/0/certificate-installation-java-based-web-servers-tomcat-using-keytool
and created a domain.keystore file, but I'm not sure if that's the right thing to do or not. My configuration in Jboss now looks like this:
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
<ssl name="mydomain" password="*****" protocol="TLSv1" certificate-key-file="../standalone/configuration/domain.keystore"/>
</connector>
But that doesn't seem to work. I get no error in the server log, the page simply times out. If i use http it works normally. Any advice?
EDIT:
I took a different approach, I generated my keystore in this way:
keytool -genkey -alias domain -keyalg RSA -keysize 2048 -keystore domain.keystore
then I uploaded the new csr info to comodo and got the three .crt certificates back. I imported them into the keystore with this command:
keytool -import -trustcacerts -alias domain -file domain.crt -keystore domain.keystore
and then I used the keystore in the standalone.xml in this way:
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
<ssl name="domain-ssl" key-alias="domain" password="******" certificate-key-file="../standalone/configuration/domain.keystore" protocol="TLSv1"/>
</connector>
The server starts, but when I try to connect to it, my browser says that the connection is untrusted:
domain uses an invalid security certificate.
The certificate is not trusted because it is self-signed.
(Error code: sec_error_ca_cert_invalid)
I finally managed to get the installation right! Here's how you do it:
Install the COMODO certificates into your keystore wit this command:
keytool -import -trustcacerts -alias <filename> -file <filename>.crt -keystore domain.keystore
in the following order:
» Root: AddTrustExternalCARoot.crt
» Intermediate 1: COMODOAddTrustServerCA.crt
» Intermediate 2: COMODOExtendedValidationSecureServerCA.crt
Then install your domain certificate:
keytool -import -trustcacerts -alias mykey -file yourDomainName.crt -keystore domain.keystore
You should use the same alias instead of mykey, that you used to generate your keystore. If you do everything correctly, you should get this output:
Certificate reply was installed in keystore
Anything else means, you probably didn't use the correct alias. The final thing you need to do is to modify your standalone.xml like this:
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
<ssl name="<domain>-ssl" key-alias="<domain>" password="******" certificate-key-file="../standalone/configuration/<domain>.keystore"/>
</connector>
And you should be good to go!
My domain provider offered me to get a SSL certificate from COMODO...
...
Any advice?
Don't pay for the certificate. You can get a free Class 1 certificate from Startcom. The Class 1 is good for server authentication without a wildcard domain. If you want an extended validation certificate or a wilcard certificate, then you will have to buy a Class 2 or higher.
Also, while Startcom issues the certificate for free, they charge for revocation because that's where the cost lies.
I'm lost on where to go from here...
Convert Intermediate CA Certificate - COMODORSAAddTrustCA.crt, Intermediate CA Certificate - COMODORSADomainValidationSecureServerCA.crt and Your PositiveSSL Certificate - mydomain.crt to PEM files. PEM are the ones that start with ----- BEGIN CERTIFICATE ----- and finish with ----- END CERTIFICATE -----.
Then, concatenate your three PEM files into a single file. The file will have three certificates in it. Call it mydomain-chain.pem, and load that into your server. Also load myserver.key into your server.
Don't do anything with Root CA Certificate - AddTrustExternalCARoot.crt. Clients have to use it as a root. There's no {use|need} to send it to the client in the ServerHello.
You can test your setup with the following. Notice how the client uses the root:
openssl s_client -connect myserver:443 -CAfile AddTrustExternalCARoot.crt
The command should end with Verify (0) OK or similar.
Failed to load keystore type JKS with path ../standalone/configuration/mydomain-chain.pem due to Invalid keystore format: which mean your keystore is not valid. Dont create new one use the keystore file you were created while submitting csr file to them. Use same keystore if you change the keystore its not accept.

Getting No self-signed cert in chain error while using orapki wallet jks_to_pkcs12 -wallet

I got the CA signed certificates and tried to import into the Oracle Wallet Manager for OHS SSL. Private Key and certificate request is generated using open ssl and so we have to create the pkcs12 cert first using the below -
openssl pkcs12 -export -name myservercert -in selfsigned.crt -inkey server.key -out keystore.p12
After that i converted this to JKS using below -
keytool -importkeystore -destkeystore mykeystore.jks -srckeystore keystore.p12 -srcstoretype pkcs12 -alias myservercert
and then imported the Intermediate certs in the JKS. After that when i am trying to convert jks to pkcs12 again using -
mw_home\oracle_common\bin\orapki wallet jks_to_pkcs12 -wallet ./ -pwd "mypassword" -keystore ./mykeystore.jks -jkspwd "mypassword"
I am getting the error - Exception : java.io.IOException: No self-signed cert in chain.
We are not using any self-signed certificate so wondering from where we are getting this issue.
I tried using the p12 keystore that i created in the very first step but there is no certificate request or certificates getting displayed in Oracle Wallet.
Please suggest what is wrong I am doing or is there any best way to import certificates in Oracle Wallet.
why did you use keytool to import intermediate certifcates and not orapki?
orapki wallet add -wallet -cert trustedcerts.crt -trusted_cert
You don't need to bother creating a JKS file. Oracle wallets are valid PKCS12 files. Just create a PEM file with full certificate chain (your private key, your cert, and the full certificate chain in a single file), then run
openssl pkcs12 -export -in certchain.pem -out ewallet.p12
The name 'ewallet.p12' is important. That is Oracle's requirement. Put this file in your wallet directory, then run
orapki wallet create -wallet . -pwd your_pass -auto_login
to create the cwallet.sso file.

Categories

Resources