How to get .crt file from .jks - java

I need to make my website SSL configured. I have the following files with me:
file.csr and
file.jks
and I need the following files to SSL enable my website:
file.crt and
file.key and
keystore
I have searched through the internet but found no help regarding. Can anyone tell me how I can get these files using the files I already have?
I have tried multiple options for conversion but nothing worked.
<Connector port="8442" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="/conf/keys/server/keystore"
keystorePass="CHANGEME"/>

Following are the commands I performed to get the desire result
Convert mobiliser.jks file to keystore.p12:
keytool -importkeystore -srckeystore mobiliser.jks -destkeystore keystore.p12 -deststoretype PKCS12
Convert keystorep.12 file to keystore:
keytool -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -destkeystore keystore -deststoretype JKS
Create key:
C:\openssl-0.9.8k_X64\bin\openssl pkcs12 -in keystore.p12 -nocerts -nodes -out mobiliser.key
Create certificate:
C:\openssl-0.9.8k_X64\bin\openssl pkcs12 -in keystore.p12 -nokeys -out mobiliser.crt

Related

How to fix "TrustAnchor is not a CA certificate" for self-signed certificates? (Java)

I'm trying to create a self-signed server certificate for my client/server application (written in Java using the Netty library). From my understanding, I have to create a CA keystore and a server keystore, sign the server certificate using the CA keystore and place the CA certificate in the client's truststore. For this purpose, I have written the following windows script:
call keytool -genkey -alias ca -keyalg RSA -keystore ca.keystore -storetype JKS -storepass changeit -keypass changeit
:: create CA keystore
call keytool -exportcert -rfc -alias ca -file truststore.pem -keystore ca.keystore -storepass changeit
:: export CA certificate
call keytool -genkey -alias server -keyalg RSA -keystore server.keystore -storetype JKS -storepass changeit -keypass changeit
:: create server keystore
call keytool -certreq -alias server -keystore server.keystore -file server_signing_request.csr -storepass changeit
:: ask CA to sign server certificate
call keytool -gencert -infile server_signing_request.csr -outfile signed_server_cert.crt -keystore ca.keystore -alias ca -storepass changeit
:: sign server certificate
call keytool -importcert -alias ca -keystore server.keystore -file truststore.pem -storepass changeit
:: import root CA certificate into server keystore
call keytool -import -alias server -keystore server.keystore -trustcacerts -file signed_server_cert.crt -storepass changeit
:: import signed server certificate into server keystore
Server code to create the SSL engine:
final KeyStore keyStore;
try (FileInputStream input = new FileInputStream(new File("server.keystore"))) {
keyStore = KeyStore.getInstance("JKS");
keyStore.load(input, "changeit".toCharArray());
}
final KeyManagerFactory factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
factory.init(keyStore, "changeit".toCharArray());
final SSLContext context = SSLContext.getInstance("TLS");
context.init(factory.getKeyManagers(), null, null);
final SSLEngine sslEngine = context.createSSLEngine();
sslEngine.setUseClientMode(false);
sslEngine.setNeedClientAuth(false);
And to create the SslContext on client side:
final SslContext sslContext = SslContextBuilder.forClient().trustManager(new File("truststore.pem")).build();
However, connection attempts from client to server result in the following exception:
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=CA, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown" is not a CA certificate
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:477)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at de.klenze_kk.chess.client.netty.MyLoggingHandler.channelRead(MyLoggingHandler.java:28)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=CA, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown" is not a CA certificate
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:326)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:269)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1339)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1214)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1157)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1061)
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1048)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:995)
at io.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1550)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1396)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1237)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1286)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:507)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:446)
... 21 more
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=CA, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown" is not a CA certificate
at java.base/sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:369)
at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:263)
at java.base/sun.security.validator.Validator.validate(Validator.java:264)
at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:313)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:276)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:141)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1317)
... 35 more
Caused by: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=CA, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown" is not a CA certificate
at java.base/sun.security.validator.PKIXValidator.verifyTrustAnchor(PKIXValidator.java:393)
at java.base/sun.security.validator.PKIXValidator.toArray(PKIXValidator.java:333)
at java.base/sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:366)
... 41 more
Can someone help, please? What am I doing wrong?
It looks like you are in the right direction but missing couple of essential parts when creating the CA and the Server certificates.
I would recommend to use the option genkeypair instead of genkey and you also need some extension to give your certificates some additional capabilities.
For the CA I would recommend:
-ext KeyUsage=digitalSignature,keyCertSign -ext BasicConstraints=ca:true,PathLen:3
And for the server I would recommend:
-ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement -ext ExtendedKeyUsage=serverAuth,clientAuth -ext SubjectAlternativeName:c=DNS:localhost,IP:127.0.0.1
Next to that you need to make sure to temporally import the CA certificate into the Server certificate before replacing the unsigned server certificate with the signed one. This is something which is weird in my opinion but oracle/sun just designed it this way. In your steps you have done this correctly, but you can remove the CA certificate when you have imported the signed server certificate.
You also don't need the -trustcacerts option when importing the signed server certificate. And I would recommend to use importcert instead of import command when importing the signed server certificate.
So to sum up I would recommend to execute the following steps:
1. Create CA keystore
keytool -genkeypair -alias ca -keyalg RSA -keystore ca.keystore -storetype JKS -storepass changeit -keypass changeit -ext KeyUsage=digitalSignature,keyCertSign -ext BasicConstraints=ca:true,PathLen:3
2. Create server keystore
keytool -genkeypair -alias server -keyalg RSA -keystore server.keystore -storetype JKS -storepass changeit -keypass changeit -ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement -ext ExtendedKeyUsage=serverAuth,clientAuth -ext SubjectAlternativeName:c=DNS:localhost,IP:127.0.0.1
3. Create certificate signing request (CSR) for the server
keytool -certreq -alias server -keystore server.keystore -file server_signing_request.csr -storepass changeit -keyalg rsa
4. Sign the server CSR with the CA
keytool -gencert -infile server_signing_request.csr -outfile signed_server_cert.crt -keystore ca.keystore -alias ca -storepass changeit -ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement -ext ExtendedKeyUsage=serverAuth,clientAuth -ext SubjectAlternativeName:c=DNS:localhost,IP:127.0.0.1 -rfc
5. Export the CA certificate
keytool -exportcert -rfc -alias ca -file truststore.pem -keystore ca.keystore -storepass changeit
6. Import the CA certificate into the server keystore
keytool -importcert -alias ca -keystore server.keystore -file truststore.pem -storepass changeit
7. Import the signed server certificate
keytool -importcert -alias server -keystore server.keystore -file signed_server_cert.crt -storepass changeit
8. Delete the imported CA certificate from the server keystore
keytool -delete -alias ca -keystore server.keystore -storepass changeit
Could you retry with these commands and share the results?
By the way I have written a tutorial here which might be helpful for you :) See: https://github.com/Hakky54/mutual-tls-ssl

How to install GoDaddy SSL certificates in Tomcat without CSR?

One of our clients purchased wild card SSL certificates (*.example.com)
from GoDaddy and he simply downloaded without giving CSR data. We have 3 files in that zip file. Those are fce4f111a61ea3f4.crt, gd_bundle-g2-g1.crt and gdig2.crt.pem.
I searched so many articles regarding this but everyone is saying first take the CSR data from your server and past it in the GoDaddy for getting SSL certificates.
In my case we didn't provide CSR data to GoDaddy, which means I don't have the keystore file.
Now, I tried to install certificates without keystore to my server. For that I used the below commands with no success:
keytool -import -alias root -keystore tomcat.keystore -trustcacerts -file fce4f111a61ea3f4.crt
keytool -import -alias interm -keystore tomcat.keystore -trustcacerts -file gd_bundle-g2-g1.crt
keytool -import -alias tomcat -keystore tomcat.keystore -trustcacerts -file gdig2.crt.pem
I'm assuming you already have keystore maintained as per your statements above. Take a backup of your keystore first in order to avoid any mishap.
Apart from the files you have, you should also has Private Key of your generated certificate.
Now follow the steps as ordered.
Delete any existing entries from keystore file first.
keytool -delete -alias tomcat -keystore domain.jks
You may also view any other existing entries by keytool -list -keystore domain.jks delete them as well.
Now export the certificate and private key into PKCS12 file
openssl pkcs12 -export -in fce4f111a61ea3f4.crt -inkey private.key -out cert_and_key.p12 -name tomcat -CAfile gd_bundle-g2-g1.crt -caname root
If you receive similar to following error
unable to load private key
139995851216720:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:707:Expecting: ANY PRIVATE KEY
It means your private.key isn't in proper format, you need to change encoding to ASCII text run following command to convert your private key
# You can do a dry run before manipulating the actual file
tail -c +4 private.key | file -
# Change encoding
tail -c +4 private.key > private.key
Import PKCS12 file into JKS keystore:
keytool -importkeystore -srckeystore cert_and_key.p12 -srcstoretype PKCS12 -alias tomcat -keystore domain.jks
Now import root certificate into JKS keystore (with root alias)
keytool -import -trustcacerts -alias root -file $certdir/gd_bundle-g2-g1.crt -noprompt -keystore domain.jks
Add following in server.xml
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="150"
SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS"
keystoreFile="/path/to/keysore/domain.jks" keystorePass="xxxxxx"
ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_RC4_128_SHA" />
Don't forget to replace xxxxxx with your JKS keystore password and keystoreFile parameter
Done. Now restart your Tomcat server and listen to your log file
sudo service tomcat7 restart
sudo tail -f /var/log/tomcat7/catalina.out
Note: replace domain.jks with your actual keystore file.
Following the info here and other places, this worked for me on TC9 on windows:
Make sure path has a Java Home:
set PATH=%PATH%;C:\Program Files\Java\jre1.8.0_281\bin
Create keystore:
keytool -genkey -alias server -keyalg RSA -keysize 2048 -keystore mydomain.jks
Extract .csr:
keytool -certreq -alias server -file C:\pathtoit\csr.txt -keystore mydomain.jks
Give csr.txt to godaddy and obtain the certificate
Import the bundle and the .crt file:
keytool -import -trustcacerts -alias intermediate -file gd_bundle-g2-g1.crt -keystore mydomain.jks
keytool -import -alias server -keystore mydomain.jks -trustcacerts -file 24234234.crt
Note: use Keystore Explorer if you want to see what's happening.
Then in server.xml:
<Connector port="443" maxHttpHeaderSize="8192" maxThreads="100"
minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
SSLEnabled="true" clientAuth="false"
sslProtocol="TLS" keyAlias="server"
keystoreFile="C:\pathtoit\mydomain.jks" keystorePass="xxxx" />

Hybris Commerce ERR SSL VERSION OR CIPHER MISMATCH

I have created a certificate with OpenSSL
openssl genrsa -des3 -out server.key 2048
openssl rsa -in server.key -out server.key
openssl req -new -key server.key -out server.csr
keytool -import -trustcacerts -alias server.key -file server.crt -keystore
and placed keystore.jks into ${catalina.home}/lib/
server.xml
<Connector port="9002"
maxHttpHeaderSize="8192"
maxPostSize="4194304"
maxThreads="150"
protocol="org.apache.coyote.http11.Http11Protocol"
executor="hybrisExecutor"
enableLookups="false"
acceptCount="100"
connectionTimeout="20000"
disableUploadTimeout="true"
URIEncoding="UTF-8"
SSLEnabled="true"
scheme="https"
secure="true"
clientAuth="false"
sslProtocol = "TLS"
sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"
keystoreFile="${catalina.home}/lib/keystore.jks"
keystorePass="123456"
On Chrome it gives following error:
This site can’t provide a secure connection
13.236.191.242 uses an unsupported protocol.
ERR_SSL_VERSION_OR_CIPHER_MISMATCH
Unsupported protocol
The client and server don't support a common SSL protocol version or cipher suite.
curl -Iv https://11.231.191.212:9001/
Trying 11.231.191.212...
TCP_NODELAY set
Connected to 11.231.191.212 (11.231.191.212) port 9001 (#0)
schannel: SSL/TLS connection with 11.231.191.212 port 9001 (step 1/3)
schannel: checking server certificate revocation
schannel: using IP address, SNI is not supported by OS.
schannel: sending initial handshake data: sending 156 bytes...
schannel: sent initial handshake data: sent 156 bytes
schannel: SSL/TLS connection with 11.231.191.212 port 9001 (step 2/3)
schannel: failed to receive handshake, need more data
The problem was that I was creating a Self-signed certificate with OpenSSL. But when I generated the certificate from java Keystore then it works perfectly.
keytool.exe -genkey -alias tomcat -keyalg RSA -keystore c:\tomcatkeys
The reason was OpenSSL and keystore produce certificate in different file formats. You see the difference from the link below.
https://security.stackexchange.com/questions/98282/difference-between-openssl-and-keytool

nginx and tomcat ssl issue - SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

Since my site ssl cert was expired I've renewed it and added new cert to keystore, but after that I am getting 502 when called the site url. Below you can see nginx config and tomcat configs for ssl.
Error I am getting in nginx error log is
SSL_do_handshake() failed (SSL: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure) while SSL handshaking to upstream, client: 120.6.20.134, server: app.somewhere.com, request: "GET /favicon.ico HTTP/2.0", upstream: "https://53.10.10.10:8443/favicon.ico", host: "app.somewhere.com", referrer: "https://app.somewhere.com/board/index.jsp"
server nginx version: nginx/1.12.1
nginx config
server {
listen 443;
server_name app.somewhere.com;
root /usr/share/tomcat8/webapps;
ssl on;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_certificate /opt/jdk1.8.0_45/jre/lib/security/app_somewhere_com.pem;
ssl_certificate_key /opt/jdk1.8.0_45/jre/lib/security/app_somewhere_com.key;
ssl_dhparam /etc/nginx/certs/dhparam.pem;
proxy_ssl_server_name on;
location / {
proxy_read_timeout 120s;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://app.somewhere.com:8443;
}
}
tomcat server.xml
<Connector port="8443"
maxThreads="100"
scheme="https"
secure="true"
SSLEnabled="true"
keystoreFile="/opt/jdk1.8.0_45/jre/lib/security/my-keystore.jks"
protocol="org.apache.coyote.http11.Http11NioProtocol"
keystorePass="mypass"
clientAuth="false"
sslProtocol="TLS"
proxyPort="443"/>
Found the issue, the certificate was imported to the wrong key-store. So I've created new key-store using certificate and private-key that I had using following commands.
create new keystore
openssl pkcs12 -export -in cert.crt -inkey private-key.key -certfile cert.crt -name "tomcat" -out keystore.p12
convert keystore to jks format
keytool -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype JKS
Then set the keystore.jks path in tomcat server.xml

unable to find valid certification path

I have created a certificate in my system using this command:
keytool -export -file test.cert -keystore test -storepass 123456 -alias sriram
Ans: Certificate stored in file <test.cert>.
I have imported this certificate in cacerts of new system using the command :
keytool -importcert -trustcacerts -file "path-to-public-cert" -keystore JAVA_HOME/jre/lib/security/cacerts".
The output is something like this:Trust this certificate? [no]: yes Certificate was added to keystore.
But still I am getting the link error when I run my jar file in new system...Where I went wrong??
Try to read the Apache Tomcat SSL Configuration How-To.
In Edit the Tomcat Configuration File paragraph it explain that you can had the keystoreFile attribute to the connector configuration.
<Connector
port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="${user.home}/.keystore" keystorePass="changeit"
clientAuth="false" sslProtocol="TLS"/>

Categories