How to Store Certificate Files Securely in Spring Cloud Config Server? - spring

I have a .pfx file that I use for communicating with a web service. I load it from classpath in development environment like this:
application.yml
my-config:
certificate: classpath:/certificate/dev/mycertificate.pfx
Service.java
SSLContext sslContext = SSLContext.getInstance(SSL_CONTEXT_PROTOCOL);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore keystore = KeyStore.getInstance("JKS");
Resource certificateResource = myConfig.getCertificate();
keystore.load(certificateResource.getInputStream(), myConfig.getCertPassword().toCharArray());
certificateResource.getInputStream().close()
keyManagerFactory.init(keystore, myConfig.getCertPassword().toCharArray());
sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
requestContext.put(SSL_SOCKET_FACTORY, sslContext.getSocketFactory());
This works fine in development environment. The problem is, I do not want to just push the certificate resource to git repo. Also I cannot put the file inside the server because we use pivotal application service for hosting the app. So is there any way I can securely store the certificate file in the config server or anywhere else?
Thanks.

You could put the cert into Spring Cloud Config Server. If you are using Spring Cloud Services for VMware Tanzu you can follow these instructions and store the value into CredHub through SCS.
Alternatively, you could store encrypted values in a Git backend and SCS will decrypt them for you. See instructions here. You could also store things in Vault, but Vault is not provided by the SCS for VMware Tanzu tile. You'd have to run your own Vault server. Instructions for using Vault. Both of these options, I feel, are a bit more work than using SCS's support for CredHub.
If you are trying to use only OSS Spring Cloud Config, you can do that too, but it's more work, more than I can cover here. That said, all three of these options are available there as well:
CredHub backend w/SCS.
Git + encrypted properties.
Vault backend w/SCS.
Vault and CredHub both have certificate types specifically for storing certificates. I do not believe SCS exposes these options, so you would be just storing the text representation of your certificate.
All of these options assume that you want to use Spring Cloud Config server. If you wanted an option not tied to Spring, you could use the CredHub Service Broker tile. This allows you to store items in CredHub and then present them as bound services. With it, you could create a bound service that represents your certificate, bind that to the apps that require it, and then fetch your certificate from VCAP_SERVICES like any other bound service.
The downside of this approach is that VCAP_SERVICES is an environment variable, so it's storing text only and there are limits to how much information can be stored.

Related

How to generate a trusted ssl certificate for the backend of an application developed with spring-boot

I have a web application developed with spring boot and Angular. The frontend is running on ngnix web server , the backend is running on embedded tomcat for spring boot , both of them are hosted on a Debian VM on ovh cloud, so it's secured with ovh basic Let's Encypt basic security for ssl offered by OVH.
My problem is that the certificate is regenerated (each 3 months ovh regenerate a new one ) and my backend could not recognize anymore the calls coming from the front end.
I made some researches on how to use the certificates generated by ovh ( use the privatekey.pem and fullchain.pem (under /etc/letsencrypt/live/mydomain) with openssl to generate a PKCS12 file to be put on the backend server )
I put the generated .p12 file in my spring app and configured mu application.properties but with no success!
server.ssl.key-store-type=PKCS12
# The path to the keystore containing the certificate
server.ssl.key-store=classpath:keystore/my-keystore.p12
# The password used to generate the certificate
server.ssl.key-store-password=mypassword
# The alias mapped to the certificate
server.ssl.key-alias=myalias
So how do I generate a trusted SSL certificate for my backend server?
I don't know if I'm in a good way with these steps or not, since I'm totally new with all this stuff but If someone could explain me the flow, how to proceed I will be so much grateful !
Thanks in advance

Azure service for hosting zip file securely

I am running a spring boot app which internally uses secure bundle zip file of size 13kb . I want to host the file to remote server securely and encrypted . The infrastructure I am in is azure . Which azure service I can use to host my zip file securely ? Can I use azure key value to access my zip file ?
You can store the Zip file in Azure Blob storage. Azure Storage uses server-side encryption (SSE) to automatically encrypt your data when it is persisted to the cloud. You can configure your storage account to accept requests from secure connections only by setting the Secure transfer required property for the storage account.
You could then restrict access to the storage blob via Shared Access Signature.
If you wanted to be extra secret squirrel, you could even enable CMK (Customer Managed Keys) for the encryption to make doubly sure nobody is looking at your secret sauce.
https://learn.microsoft.com/en-us/azure/storage/common/storage-require-secure-transfer
https://learn.microsoft.com/en-us/azure/storage/common/customer-managed-keys-configure-key-vault?tabs=portal
https://learn.microsoft.com/en-us/azure/storage/blobs/security-recommendations
You could theoretically host your zip file in Key Vault if you serialize it to a text file. But I think that's a bad idea.
The right service is Azure Storage File Share.

Error: unable to verify the first certificate - Springboot

I have written a restful API project which is developed using spring boot and I am using the embedded tomcat and running a jar on a linux server.
The APIs are live at:
https://api.arevogroup.com:8089/api/regions
and I can see the verified and correct SSL as well as in the given screenshot.
but I am getting an this exception in the postman when I call these apis.
These APIs are consumed by a Xamrin based app which seems to work all good when consumed using iPhone but gives this same exception when the APIs are accessed via android.
I guess, the way I have generated the ssl certificate has some issues.
I have used a pfx file and my SSL config in properties file looks like this:
###SSL Key Info
security.require-ssl=true
server.ssl.key-store-password=PASSWORD
server.ssl.key-store=classpath:ssl_pfx.pfx
server.ssl.key-store-type=PKCS12
I have 2 questions, if disable the ssl verification, would the communication still be encrypted or not? (man in the middle attack is still possible but the info will still be encrypted, right?).
If not, how can I fix this?
You can't disable the verification of the server certificate. No browser will allow you to do it, except on an exceptional basis (the user must confirm the exception). If the client disables the verification, than the communication will be encrypted (i.e. no passive attack will be possible).
The errors you see are cause by a misconfiguration of your server.
Your certificate chain contains just the certificate for your server and lacks the intermediate certificate CN=Go Daddy Secure Certificate Authority - G2. You need to download it from Go Daddy (it is the one named gdig2.crt.pem) and add it to your keystore.
Refer to this question on how to do it.
Some browsers cache intermediate certificates and are able to verify your site even if one certificate is missing. However you should not rely on it.
security.require-ssl=true
server.ssl.key-store-password=PASSWORD
server.ssl.key-store=keystore.jks
server.ssl.key-store-provider=SUN
server.ssl.key-store-type=JKS
Used the jks file instead of pfx and it worked all good. Thought to share with others too.

How to pass password\encryption key to Heroku application

I'm deploying my Spring boot application into Heroku server via git deployment. There are passwords and api secrets in my application.yml. Those properties are encrypted with Jasypt. One thing I don't understand is: how to pass jasypt decryption password into deployed application for startup?
Heroku has Config Vars, but they do not seem secure, considering that all of them could be revealed on the dashboard
Is there a secure way to send a password into deployment?
the Config Vars is the accepted mechanism to pass runtime information to the apps upon deployment;
It is pretty secure if the access to the Dashboard is controlled of course (those settings are never exposed or logged), only the owner can reveal the values.

securing access to spring cloud configserver

I was wondering how people are handling security aspects when using Spring Cloud Config.
I'm planning to use Spring Cloud Config Server and Client together with Spring Boot. From an implementation point of view this is quite straight, but how do you deal with the risk of disclosing password/access to every developer.
e.g. you run one central configserver containing configurations for all environment. In the bootstrap.yml of the config client app you'll have to configure the username/password to access the configserver. So far so good, but when I know commit the username/password in the respective yml file, then every developer has potential access to all environments by just switching the profile from e.g. development to production (please let's not start a discussion why not every developer needs access to production).
I'm aware that I can encrypt all passwords in the configuration, we do this, but that's not what I'm looking for. Encryption is just a feature to not have the passwords being stored plaintext in the files, but the user does not really need to know the plain password to get access if he has access to the configserver in the first place.
This is also about avoiding mistakes during development... its just to easy to switch the local environment to connect to production or any other environment.
So how are people dealing with this? Do you inject a different bootstrap.yml in development then in other environments? if so how do you administrate/propagate these?
Do you set the password for the configuration user on the comandline?
...?
We use variables and default values for config server URL, user and password
${config_username:user}:${config_password:password}#${config_server:conf.mydomain.com}
Default values can be valid credentials for development environment this way you simply run it while you develop. When you deploy to production simply set those environment variables and your application will connect to a different config server
I was thinking about this myself and came up with 3 options. In all cases, use {cipher} values in repos for sensitive data and disable various actuator endpoints that would allow decryption or property value lists.
Have two config servers, one for dev and one for prod, with no dev access to the prod server, controlled by credentials provided to the prod client at runtime.
Perform the decryption client side, using a secret provided to the prod client at runtime.
Explicitly define a prod profile and block access to URLs containing that profile from non-prod servers.

Resources