Friday, February 28, 2020

Spring Boot property encryption using Jasypt

In this post I will demonstrate how to encrypt data on Spring Boot property file using Jasypt (Java Simplified Encryption). For this I will use code base of my previous post "Spring Boot REST API CRUD operations with MySQL with Spring Data" you can download the code base on github.

Prerequisites 
  1. You should have install java 1.8 or above.
  2. You should have Eclipse installed in your PC.
  3. Your PC should setup Maven installed and configured.
  4. MYSQL server need to be installed. 

Install Jasypt (Java Simplified Encryption) 

In this example we have to use Jasypt to encript our passwords. So first we can download the Jasypt from official web site on http://www.jasypt.org/download.html

Extract in to folder and navigate to bin folder and you can run encrypt.bat/encrypt.sh with relevant parameters. 

encrypt.bat input="This is my message to be encrypted" password=MYPASSWORD_SECRET 

input
This is the password that we going to use in the application

password
This is the secret to decrypt the password

Then you can see similar output as figure below.

Sample encrypt command 
Make sure to use user password for input parameter and generate the encrypted string



Dependency Configure

I will use following project https://github.com/NirmalBalasooriya/RestApiSpringBoot for the demonstration of this post. Check out the project in to you IDE.  First lets add Jasypt  dependency in to pom.

<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot</artifactId>
<version>3.0.2</version>

</dependency>


Update the project pom file as show below 


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.nirmal.springbootrest</groupId>
  <artifactId>RestApiSpringBoot</artifactId>
  <version>0.0.1-SNAPSHOT</version>

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
    </parent>
<dependencies>
<!-- Compile -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- Provided -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- Runtime -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.1.0.jre8</version>
</dependency>

<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot</artifactId>
<version>3.0.2</version>
</dependency>

</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>



Application Configuration

First we have to add following configurations in to Spring boot configurations. For this we have two options either we can add the configuration detail in to default application.property file or we can add separate property file to hold jasypt configurations. I will add these configurations in to existing property file.

jasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator
jasypt.encryptor.algorithm=PBEWithMD5AndDES

Then we can change the spring.datasource.password field. we can use encrypted script there. Make sure to us following format

ENC(generated encrypted string)

EG:
ENC(Qh5TpYelwS//T13si7t218U6t42iM4B2)

So our final application property file would be something similar to this.

#==== connect to mysql ======#
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:sqlserver://localhost;databaseName=TestDB
spring.datasource.username=nirmal
spring.datasource.password=ENC(Qh5TpYelwS//T13si7t218U6t42iM4B2)
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.database-platform=org.hibernate.dialect.SQLServer2012Dialect

spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=false
spring.jpa.properties.hibernate.format_sql=true

#==== Logging configurations ======#
logging.level.root=WARN,INFO,ERROR
logging.level.com.baeldung=TRACE

jasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator
jasypt.encryptor.algorithm=PBEWithMD5AndDES

#jasypt.encryptor.password=MYPASSWORD_SECRET




Enable Application Configuration

Lets enable the encrypted configuration by adding following annotation in our spring boot initialization class  we have to use @EnableEncryptableProperties configuration annotaion. So final class would be something similar below.


package com.nirmal.springbootrest;

import javax.sql.DataSource;

import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

/**
 * Spring Boot initialization class of the ResrApiSpringBoot project
 * 
 * @author Nirmal Balasooriya
 *
 */

@ComponentScan({ "com.nirmal.springbootrest", "com.nirmal.springbootres.controller" })
@EnableJpaRepositories("com.nirmal.springbootrest")
@SpringBootApplication(scanBasePackages = { "com.nirmal.springbootres.controller" })
@EnableEncryptableProperties
//@PropertySource(name="EncryptedProperties", value = "classpath:encrypted.properties")
public class AppInitializer extends SpringBootServletInitializer {

@Autowired
DataSource dataSource;

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AppInitializer.class);
}

public static void main(String[] args) {
SpringApplication.run(AppInitializer.class, args);
}

}


Note-
If you need to use separate property file for encrypted properties you can use following

@PropertySource(name="EncryptedProperties", value = "classpath:encrypted.properties")



Run the application


In order to run first we have to perform maven install command and then we can run the application

in command line we can use following command to run the application

mvn -Djasypt.encryptor.password=MYPASSWORD_SECRET spring-boot:run

Here we are passing the secret which we used in password encryption process. it is possible to configure the secrent in property file as well. For that you can use following property.(Which I commented on my example since I'm passing it as command line argument)

jasypt.encryptor.password=MYPASSWORD_SECRET

One successfully started the application you should be able to see similar result as below. 




Also you should be see table has been created on your configured Database and you can access the web service from following URL. 

With following out put on web browser.



Lets Test the application 


Then lets add new Book in to API


curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d "{ \"isbmNumber\":\"9999\", \"name\":\"How to develop API\", \"description\":\"sample book\", \"auther\":\"Nirmal Balasooriya \" }" http://localhost:8080/saveOrUpdate

  
For this one following output will return


{"code":"1","desc":"Book save successful","t":"9999"}


If you check the database you can see data has been inserted to the Database.


Also we can access data through API as well http://localhost:8080/findBook/9999



You can access the updated code base from following GitHub URL.


3 comments:

  1. I get this error:

    ***************************
    APPLICATION FAILED TO START
    ***************************

    Description:

    Failed to bind properties under 'spring.datasource.password' to java.lang.String:

    Reason: Failed to bind properties under 'spring.datasource.password' to java.lang.String

    Action:

    Update your application's configuration


    Process finished with exit code 0

    ReplyDelete
    Replies
    1. Hi, I have the same issue too,
      Any resolution? we use spring boot version 2.7.7, tried with jasypt 3.0.3 .
      Thanks in advance

      Delete
  2. Thus, More's ideas in Utopia would have definitely interest people. However, there are not so many followers and advocates of the society described in 'Utopia'. So why are people not interested in being Utopians.Property Management Sacramento

    ReplyDelete