I configure SSL in my current spring-boot project this way:
generation of the keystore file:
keytool -genkey -alias ... -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validi
ty 3650 -dname "CN=Kleber Mota, OU=lojadesoftware, O=Itabuna, L=Brazil, ST=Unknows, C=BR" -keypass ... -storepass ...
application.properties (added this lines):
# EMBEDDED SERVER CONFIGURATION
server.port=8443
server.ssl.enabled=true
server.ssl.key-alias=...
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-type=PKCS12
server.ssl.key-store-password=...
server.ssl.key-password=...
after that, when I run the application and go to url localhost:8443 I only got an error "Empty response from server".
Anyone can give a hint of what I am missing here?
if your application is running and has explicit mapping for (/) try the following, it should work
curl k https://localhost:8443
curl -k https://localhost:8443 ( this one is insecure)
curl -k -1 https://localhost:8443
Related
I've seen some similar threads but None of them helped me.
I generate new key pair for the server using command:
keytool -genkey -alias test-tls-server -keystore TestServerKeyStore.jks -storetype JKS -keyalg RSA -sigalg SHA1withRSA -validity 365
I export servers certificate to cer file:
keytool -export -alias test-tls-server -file test_server.cer -keystore TestServerKeyStore.jks
I create client key store using command:
keytool -import -keystore TestClientKeyStore.jks -storetype JKS -alias test-tls-server -file test_server.cer
Note that the certificate is self-signed purposely.
I also configure locations and passwords for keystores on both sides:
System.setProperty("javax.net.ssl.keyStore", <path_to_keystore_file>);
System.setProperty("javax.net.ssl.keyStorePassword", <pass_to_keystore>);
When I try to connect to server, on client side everything looks OK until I try to read something from the socket.
On server side I get the following error:
javax.net.ssl.SSLHandshakeException Exception message: Received fatal
alert: bad_certificate
This code worked for previous certificate but since it expired I need to generate the new one. I have no clue what I'm doing wrong here.
I would appreciate any help.
I have Spring Boot (backend) application which is running on Tomcat (port 8080) and Angular app (frontend) (port 4200).
Frontend consumes rest API from backend. How can I secure my applications using Nginx with SSL?
I have heard i could configure my Spring Boot as reverse proxy in nginx and then secure it with SSL but i dont know how to do it.
both spring boot and nginx should configure to get https.
for java and spring boot you should create certificate file using keytool that you can find it in jdk/bin.
keytool -genkey -alias <desired certificate alias>
-keystore <path to keystore.pfx>
-storetype PKCS12
-keyalg RSA
-storepass <password>
-validity 730
-keysize 2048
then put .p12 file beside application.properties.
for spring boot you should add this in your application.properties or application.yml:
server.ssl.enabled=true
server.ssl.key-store=classpath:client.p12
server.ssl.key-store-password=<password>
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=<desired certificate alias>
after that we should create certificate file for angular and nginx and add some configuration to nginx.conf.
for creating certificate file you can use openssl tool.
create openssl-custom.cnf file add put blow code in that:
[req]
default_bits = 2048
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn
[dn]
C = US
ST = utah
L = US
O = IT
OU = IT Section
emailAddress = info#example.com
CN = localhost
[v3_req]
subjectAltName = #alt_names
[alt_names]
DNS.1 = *.localhost
DNS.2 = localhost
and then open terminal or cmd and run this command:
#!/bin/bash
openssl req \
-newkey rsa:2048 \
-x509 \
-nodes \
-keyout server.key \
-new \
-out server.crt \
-config ./openssl-custom.cnf \
-sha256 \
-days 365
then put server.key and server.crt in you angular project and add these code to nginx.conf:
listen 443 ssl;
ssl_certificate <path to .crt file>/server.crt;
ssl_certificate_key <path to .key file>/server.key;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
! for using ssl in nginx you should use port 443 not 80;
! for testing your angular open new tab and don't use your old tab
jdbc:mysql://localhost:3306/MyDb?verifyServerCertificate=true&useSSL=true&requireSSL=true
I downloaded the public certificate from the mySql server and put it into cacerts like this:
keytool.exe -import -alias mysql_dev \
-keystore /c/dev/tools/Java/jre1.8.0_131/jre/lib/security/cacerts \
-file rds-combined-ca-bundle.pem
I generated new keys using keytool like this:
keytool.exe -genkeypair -alias adam \
-keypass changeit \
-keysize 1024 \
-keystore /c/dev/.secure/haa2xt.jks \
-storepass changeit
So now I can see that Java is picking up both my key from the keystore and the server certificate from the truststore, but still I'm getting the PKIX error.
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target
I added this debug param to the command line and got some more info which all looks good, and I can see the mySql certificate in there.
-Djavax.net.debug=all
trustStore is: c:\dev\tools\java\jdk1.8.0_131\jre\lib\security\cacerts
trustStore type is : jks
[.....]
keyStore is : C:/dev/.secure/haa2xt.jks
keyStore type is : jks
keyStore provider is :
init keystore
init keymanager of type SunX509
*** found key for : adam
What have I done wrong?
It turns out that the keytool import command will only import the first certificate in the PEM file when there are more than one.
This was the only one I checked for as well, so I thought it was fine when actually there were about 15 that I still hadn't imported.
I used this tool to import them all: https://github.com/use-sparingly/keyutil
I have an instance of glassfish 4.1.1 running and I added my own certificate to my applications, until then everything is Ok..
But, when I tried to access the glassfish admin(DAS) the connection was unstrusted and the button to add exception disappears.
Then I found some interesting links talking about that, like :
Right way to configure Glassfish SSL certificate nickname?
I tried this:
asadmin enable-secure-admin --adminalias=myNewAlias --instancealias myNewAlias
asadmin restart-domain domain1
This way the untrusted connection message disappears and the certicate properly appears, but when I try the authentication throw an error:
https://myUrl:4848/j_security_check
According to the comments of the answer from the link, it is very similar what that guy had but I could not solve it doing:
Removing the s1as certificate from ~.gfclient/truststore
Restart the domain with my new alias cert
How could I change the s1as certificate properly? In order to my DAS works...
I'am using Ubuntu 14 with java-1.8.0-openjdk-amd64.
Step 1:
Step 2:
The server log showing these lines:
[2016-10-18T10:38:12.565+0200] [glassfish 4.1] [SEVERE] []
[org.glassfish.admingui] [tid: _ThreadID=51
_ThreadName=admin-listener(2)] [timeMillis: 1476779892565] [levelValue: 1000] [[ javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target;
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target; restRequest:
endpoint=https://localhost:4848/management/domain/anonymous-user-enabled
attrs={} method=GET]]
I finally solved it, why it was happening? Using the #Mike explanation:
That is because there is both a keystore and a truststore for
GlassFish, and the Admin console effectively uses 2-way SSL
authentication for the initial login. If you change the s1as
certificate, you will also need to change the glassfish-instance
certificate
In my case I was trying to use my own certificate but I did not delete the oldest certificates properly on cacerts.jks and keystore.jks files.
I was running the code bellow without firstly remove the s1as and glassfish-instance from files, that was my wrong step...
asadmin enable-secure-admin --adminalias=myNewAlias --instancealias myNewAlias
To your Domain Administration Server (DAS) on Glassfish 4.1.1 run with your own certificate you must follow these steps:
1) Insert your own certificate into cacerts.jks and keystore.jks files:
In my case I am using certificate pkcs12:
keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore keystore.jks -srckeystore myOwnCert.p12 -srcstoretype PKCS12 -srcstorepass changeit -alias myOwnAlias
keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore cacerts.jks -srckeystore myOwnCert.p12 -srcstoretype PKCS12 -srcstorepass changeit -alias myOwnAlias
If you have another kind of certificate you must search how to insert inside this two files your certificate type:
$GLASSFISH_HOME/domains/domain1/config/cacerts.jks - truststore -
holding all the public keys
$GLASSFISH_HOME/domains/domain1/config/keystore.jks - keystore - holding all the private keys
References:
Session 6. Security configuration before first startup:
https://www.nabisoft.com/tutorials/glassfish/installing-glassfish-41-on-ubuntu
http://peter-butkovic.blogspot.com.es/2013/02/glassfish-default-keystore-and.html
https://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html?jn9ed3e997=3
https://glassfish.java.net/docs/4.0/security-guide.pdf
2) Delete the oldest self-signed certificates:
By default, when you run the command enabled-secur-admin the certificate assigned to this instance is s1as and the public is glassfish-instance, as explained by #Mike into another stack-overflow question the certificates remains even if you force to run with another certificate. Delete both using these commands:
#Restart your domain without secure-admin
$GLASSFISH_HOME/bin/asadmin disable-secure-admin
#Go to your domain config folder to remove the certificates:
cd $GLASSFISH_HOME/domains/domain1/config/
keytool -delete -alias s1as -keystore keystore.jks -storepass changeit
keytool -delete -alias glassfish-instance -keystore keystore.jks -storepass changeit
keytool -delete -alias glassfish-instance -keystore cacerts.jks -storepass changeit
keytool -delete -alias s1as -keystore cacerts.jks -storepass changeit
References:
Thanks #Mike: Right way to configure Glassfish SSL certificate nickname?
https://glassfish.java.net/docs/4.0/security-guide.pdf (page ~80)
3) Restart the security-admin with your own alias set on the first step
$GLASSFISH_HOME/bin/asadmin enable-secure-admin --adminalias=myOwnAlias --instancealias myOwnAlias
$GLASSFISH_HOME/bin/asadmin restart-domain
In theory, it is done, You'll be able to access the DAS with your own certificate... ;)
I'm trying to get a very basic Grizzly server up and running to allow for one-way SSL (HTTPS) connections to access jax-rs REST services. Eventually I want two-way SSL security.
I've gone through many of the examples and I just can't get anything to work. I keep running into a SSL Handshake error. Clearly I must be doing something stupid. Any help is appreciated.
Here is my code to start my embedded Grizzly server using the Jersey wrapper classes:
public static HttpServer startHttpsServer(URI listenerURI) throws IOException {
ResourceConfig resourceConfig = new ResourceConfig().packages("ws.argo.experiment.ssl");
// First I tried this configuration using the certs from the Jersey sample code
// Grizzly ssl configuration
SSLContextConfigurator sslContext = new SSLContextConfigurator();
// set up security context
sslContext.setKeyStoreFile("./src/main/resources/keystore_server"); // contains server keypair
sslContext.setKeyStorePass("asdfgh");
sslContext.setTrustStoreFile("./src/main/resources/truststore_server"); // contains client certificate
sslContext.setTrustStorePass("asdfgh");
// Then I tried just using a default config - didn't work either
// sslContext = SSLContextConfigurator.DEFAULT_CONFIG;
if (!sslContext.validateConfiguration(true)) {
LOGGER.severe("Context is not valid");
}
LOGGER.finer("Starting Jersey-Grizzly2 JAX-RS secure server...");
HttpServer httpServer; //= GrizzlyHttpServerFactory.createHttpServer(listenerURI, resourceConfig, false);
httpServer= GrizzlyHttpServerFactory.createHttpServer(
listenerURI,
resourceConfig,
true,
new SSLEngineConfigurator(sslContext).setClientMode(false).setNeedClientAuth(false)
);
httpServer.getServerConfiguration().setName("Test HTTPS Server");
httpServer.start();
LOGGER.info("Started Jersey-Grizzly2 JAX-RS secure server.");
return httpServer;
}
I also tried replaced SSLEngineConfigurator(sslContext).setClientMode(false).setNeedClientAuth(false) with null to see if that would help. Nope.
I always get the following error:
grizzly-nio-kernel(3) SelectorRunner, fatal error: 40: no cipher suites in common
javax.net.ssl.SSLHandshakeException: no cipher suites in common
%% Invalidated: [Session-2, SSL_NULL_WITH_NULL_NULL]
grizzly-nio-kernel(3) SelectorRunner, SEND TLSv1.2 ALERT: fatal, description = handshake_failure
grizzly-nio-kernel(3) SelectorRunner, WRITE: TLSv1.2 Alert, length = 2
grizzly-nio-kernel(3) SelectorRunner, fatal: engine already closed. Rethrowing javax.net.ssl.SSLHandshakeException: no cipher suites in common
To add on top of JMS comment, his answer solve my problem too .
Here is the command i used to generate the RSA certificate .
keytool -genkey -keystore ./keystore_client -alias clientKey -keyalg RSA -keypass changeit -storepass changeit -dname "CN=Client, OU=Jersey, O=changeit, L=KL, ST=SEL, C=MY"
keytool -export -alias clientKey -storepass changeit -keystore ./keystore_client -file ./client.cert
keytool -import -alias clientCert -file ./client.cert -storepass changeit -keystore ./truststore_server
keytool -genkey -keystore ./keystore_server -alias serverKey -keyalg RSA -keyalg RSA -keypass changeit -storepass changeit -dname "CN=changeit, OU=Jersey, O=changeit, L=KL, ST=SEL, C=MY"
keytool -export -alias serverKey -storepass changeit -keystore ./keystore_server -file ./server.cert
keytool -import -alias serverCert -file ./server.cert -storepass changeit -keystore ./truststore_client
I have seen this type of handshake issue come up in other posts while trying to run this issue to ground. In all of these handshake posts, the server key algorithm was never discussed - I wish it had been. It would have saved me a couple of hours. The issue that caused the above errors stemmed from assuming that the keystores that were created as part of the Jersey sample project would work. The server key was the problem.
The sample server certs are generated using the DSA algorithm. Apparently this is an issue.
I recreated the server keys using a RSA algorithm and 2048 bit strength. I restarted the server and the everything started to work like one would expect.
The error was that I assumed that the "sample" keys would work. Oops.