Skip to content

Example With SHA-512 In Spring Boot#

Example With SHA-512 In Spring Boot#

  • In this example we will use SHA-512 which use newer hashing algorithms and usually used in blockchain, but in require more bandwidth to store and transmit data.

Controller#

  • Let's create an controller with some apis as below:
Sha512Controller.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.springboot.security.hash.app.controller;

import com.springboot.security.hash.app.model.DataRequest;
import com.springboot.security.hash.app.model.MatchDataRequest;
import com.springboot.security.hash.app.service.HashSha512Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Sha512Controller {

    @Autowired
    private HashSha512Service hashSha512Service;


    @RequestMapping(method = RequestMethod.POST, path = "v1/cipher/hash/sha512", produces = MediaType.TEXT_PLAIN_VALUE)
    public ResponseEntity<String> hashSHA512(@RequestBody DataRequest inputData) {
        return new ResponseEntity<>(hashSha512Service.hashSHA512(inputData.getData()), HttpStatus.CREATED);
    }

    @RequestMapping(method = RequestMethod.POST, path = "v1/cipher/hash/sha512/check", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Boolean> checkMatchSha512(@RequestBody MatchDataRequest inputData) {
        return new ResponseEntity<>(hashSha512Service.isSHA512Match(inputData.getRawData(), inputData.getHashedData()), HttpStatus.OK);
    }

}
  • We will need to create 2 simple models for request body as below. One is used for hashing data and the other one is used for checking raw data and hashed data.
DataRequest.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package com.springboot.security.hash.app.model;

import org.springframework.lang.NonNull;

public class DataRequest {

    private String data;

    @NonNull
    public String getData() {
        return data;
    }

    public void setData(@NonNull String data) {
        this.data = data;
    }

}
MatchDataRequest.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.springboot.security.hash.app.model;

public class MatchDataRequest {

    private String rawData;
    private String hashedData;

    public String getRawData() {
        return rawData;
    }

    public void setRawData(String rawData) {
        this.rawData = rawData;
    }

    public String getHashedData() {
        return hashedData;
    }

    public void setHashedData(String hashedData) {
        this.hashedData = hashedData;
    }
}
  • Then we also need to create a model that loads environment variables into a spring bean using @ConfigurationProperties as below.
HashConfigProperties.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package com.springboot.security.hash.app.model;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "hash")
public class HashConfigProperties {

    private Sha512 sha512;

    public Sha512 getSha512() {
        return sha512;
    }

    public void setSha512(Sha512 sha512) {
        this.sha512 = sha512;
    }
}
Sha512.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package com.springboot.security.hash.app.model;

public class Sha512 {

    private String salt;

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }
}

Service#

  • In Spring Boot we don't need to add more any dependency to do the Hashing with SHA-512, we will use MessageDigest with hash algorithm is SHA-512 that Spring Boot provided. This class provide a method getInstance with input is the name of hash algorithm to create MessageDigest.
  • What is the Message Digest? More information.
  • Now let's create HashSha512Service and add two methods hashSHA512 and isSHA512Match below for hashing data and checking the hashed data with the given hashed by using MessageDigest.isEqual.
HashSha512Service.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.springboot.security.hash.app.service;

import com.springboot.security.hash.app.model.HashConfigProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

@Service
public class HashSha512Service {

    private static final String HASH_ALGORITHM_512 = "SHA-512";

    @Autowired
    private HashConfigProperties hashConfigProperties;

    public String hashSHA512(String data) {
        byte[] hash = this.hash(data);
        return DatatypeConverter.printHexBinary(hash);
    }

    public boolean isSHA512Match(String data, String hashedData) {
        byte[] digested = DatatypeConverter.parseHexBinary(hashedData);
        byte[] reHashData = this.hash(data);
        return MessageDigest.isEqual(digested, reHashData);
    }

    private byte[] hash(String data) {
        try {
            String dataWithSalt = hashConfigProperties.getSha512().getSalt().concat(data);
            MessageDigest messageDigest = MessageDigest.getInstance(HASH_ALGORITHM_512);
            return messageDigest.digest(dataWithSalt.getBytes(StandardCharsets.UTF_8));
        } catch (Exception ex) {
            throw new RuntimeException("Can not hash Data", ex);
        }
    }

}
  • Then we will hash the data together with the salt that we load from the application.yml into the HashConfigProperties component using @ConfigurationProperties. The Salt will be any string, see the example below.
application.yml
1
2
3
 hash:
  sha512:
    salt: 98ACB4E82C38C5C2D5166EB05023CAB5455035FA4659B402FB1389C2D66455A6

Testing#

  • Now, run the Spring Boot project and try to call api v1/cipher/hash/sha512 for testing hasing data. Then you will receive the result as below

 #zoom

  • Then with the hash result above, we will use it to check with the original data by calling api v1/cipher/hash/sha512/check. Then you will see the original data and hashed data are matched.

 #zoom

  • Now let's try to change a single character in original data and check again with hashed data. Then you will see the api return failed.

 #zoom

See Also#

References#