Java HMAC hashing gives different hash values for java 8 and open JDK 17

130 Views Asked by At

I am trying to compare the hash values of file content. So basically we will get the file and the file content hash values from one system. The receiving system will read the file and generate hash using same key and compare both the hash to check if the file is modified. One System is using JAVA 8 and other is using Open JDK 17. For text files the hash value is same. but for other type files the hash values are different. Below is the code.

    import java.io.File;
    import java.io.IOException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    
    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    
    import lombok.extern.slf4j.Slf4j;
    
    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.io.FileUtils;
    import org.apache.commons.lang3.SystemUtils;
    
    @Slf4j
    public class TestHashing {
    
      private static String HMACH_KEY = "some_key";
    
      private static String generateHMACHash(String message) {
        if (message == null) {
          message = "";
        }
    
        Mac sha256HMAC = null;
        try {
          sha256HMAC = Mac.getInstance("HmacSHA256");
          SecretKeySpec secretKeySpec = new SecretKeySpec(HMACH_KEY.getBytes(), "HmacSHA256");
          sha256HMAC.init(secretKeySpec);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
          log.debug("Getting Exception in Hashing ", e.getMessage());
          e.printStackTrace();
        }
    
        return Base64.encodeBase64String(sha256HMAC.doFinal(message.toUpperCase().getBytes()));
      }
    
      public static void main(String[] args) throws IOException {
    
        String version = SystemUtils.JAVA_SPECIFICATION_VERSION;
    
        System.out.println("Java Virtual Machine specification version  : " + System.getProperty("java.vm.specification.version"));
        System.out.println("Java Virtual Machine specification vendor : " + System.getProperty("java.vm.specification.vendor"));
        System.out.println("Java Virtual Machine specification name : " + System.getProperty("java.vm.specification.name"));
        System.out.println("Java Virtual Machine implementation version : " + System.getProperty("java.vm.version"));
        System.out.println("Java Virtual Machine implementation vendor : " + System.getProperty("java.vm.vendor"));
        System.out.println("Java Virtual Machine implementation name : " + System.getProperty("java.vm.name"));
    
        String fileName = "C:\\test\\fileTest.txt";
        File file = new File(fileName);
        String data = FileUtils.readFileToString(file, "UTF-8");
        String output = generateHMACHash(data);
        System.out.println(fileName + " FILE USING JAVA VERSION" + version);
        System.out.println(output);
    
        fileName = "C:\\test\\fileTest.xlsx";
        file = new File(fileName);
        data = FileUtils.readFileToString(file, "UTF-8");
        output = generateHMACHash(data);
        System.out.println(fileName + " FILE USING JAVA VERSION" + version);
        System.out.println(output);
      }
    
    } 

// This is the working code

    private static String generateHMACHash(File file) throws Exception {
    
        Mac sha256HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(HMACH_KEY.getBytes(), "HmacSHA256");
        sha256HMAC.init(secretKeySpec);
    
        // Get file input stream for reading the file
        // content
        FileInputStream fis = new FileInputStream(file);
    
        // Create byte array to read data in chunks
        byte[] byteArray = new byte[1024];
        int bytesCount = 0;
    
        // read the data from file and update that data in
        // the message digest
        while ((bytesCount = fis.read(byteArray)) != -1) {
          sha256HMAC.update(byteArray, 0, bytesCount);
        }
    
        // close the input stream
        fis.close();
    
        // store the bytes returned by the digest() method
        byte[] bytes = sha256HMAC.doFinal();
    
        // this array of bytes has bytes in decimal format
        // so we need to convert it into hexadecimal format
    
        // for this we create an object of StringBuilder
        // since it allows us to update the string i.e. its
        // mutable
        StringBuilder sb = new StringBuilder();
    
        // loop through the bytes array
        for (int i = 0; i < bytes.length; i++) {
    
          // the following line converts the decimal into
          // hexadecimal format and appends that to the
          // StringBuilder object
          sb.append(Integer
              .toString((bytes[i] & 0xff) + 0x100, 16)
              .substring(1));
        }
    
        // finally we return the complete hash
        return sb.toString();
      } 


Ouput:

Java Virtual Machine specification version  : 17
Java Virtual Machine specification vendor : Oracle Corporation
Java Virtual Machine specification name : Java Virtual Machine Specification
Java Virtual Machine implementation version : 17.0.7+7
Java Virtual Machine implementation vendor : Eclipse Adoptium
Java Virtual Machine implementation name : OpenJDK 64-Bit Server VM
C:\test\fileTest.txt FILE USING JAVA VERSION17
VfhDrMk6e8t2bdKM0r+AeCfBA+iYNAKmBDhkvocMcpU=
C:\test\fileTest.xlsx FILE USING JAVA VERSION17
vPR0xPL0dIQgrYpSN/JJELMjFm90JoM0LqAeKL+2Yfo=

Java Virtual Machine specification version  : 1.8
Java Virtual Machine specification vendor : Oracle Corporation
Java Virtual Machine specification name : Java Virtual Machine Specification
Java Virtual Machine implementation version : 2.9
Java Virtual Machine implementation vendor : IBM Corporation
Java Virtual Machine implementation name : IBM J9 VM
C:\test\fileTest.txt FILE USING JAVA VERSION1.8
VfhDrMk6e8t2bdKM0r+AeCfBA+iYNAKmBDhkvocMcpU=
C:\test\fileTest.xlsx FILE USING JAVA VERSION1.8
n5Fb6b34VOnRUsGzYGcQn7vTAPNcLfg1zFoXJ2ZvM/w= 
0

There are 0 best solutions below