Search code examples
javaoracle-databasehashcompatibility

Using Oracle STANDARD_HASH, reproduce the hash in JAVA


I'm using the STANDARD_HASH('input','SHA256') function within Oracle to populate records with their relative hash values.

This can be reproduced by connecting to Oracle doing:

select STANDARD_HASH('1234','SHA256') 
from dual
Table X    
Column 1, Column 1-hashed    
1234, sha512hashresult    
1234, sha512hashresult    
1234, sha512hashresult    
1234, sha512hashresult    

Now whats the question; What do I have to do in JAVA in order to reproduce exactly the hash values which are produced by STANDARD_HASH in Oracle? Does anyone have experience with this?

Note; For some reason there is no seed on the recommended Oracle hash function. Does anyone know the Default seed or how to figure this out?

Background: What do i want to do? Populate the table within Oracle with Oracle-Default-Tools and use a Java program to receive the input, hash it and select the correct record in the table.

What i don't want; People who tell me how I can achieve it in a different way, I need it exactly this way otherwise save your time


Solution

  • You can do this with standard libraries. Use java.security.MessageDigest with algorithm SHA-256:

    import java.nio.charset.StandardCharsets;
    import java.security.MessageDigest;
    import javax.xml.bind.DatatypeConverter;
    ...
    
    String input = "1234";        
    byte[] hashBytes = MessageDigest.getInstance("SHA-256")
            .digest(input.getBytes(StandardCharsets.UTF_8));
    String hash = DatatypeConverter.printHexBinary(hashBytes);
    System.out.println(hash);
    

    This prints 03AC674216F3E15C761EE1A5E255F067953623C8B388B4459E13F978D7C846F4, the same string that STANDARD_HASH would return.

    As discussed in How to convert a byte array to a hex string in Java?, there are faster ways to convert a byte[] to a hex string, but DatatypeConverter.printHexBinary() has the benefit of being part of the standard library, and should be fine for most use cases.

    Java 17 added HexFormat to the standard library, which lets you replace

    String hash = DatatypeConverter.printHexBinary(hashBytes);
    

    with

    String hash = HexFormat.of().withUpperCase().formatHex(hashBytes);