3

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

a_horse_with_no_name
  • 497,550
  • 91
  • 775
  • 843
Oliver
  • 918
  • 9
  • 25
  • Instead of trying to reproduce the function in Java, why don't you just call it from Java using a service let's say(and let it execute on the DB side). – g00dy Sep 12 '17 at 12:01

2 Answers2

4

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.

markusk
  • 5,979
  • 33
  • 39
1

If you're fine with using Guava on the Java side, the following code should produce equal results with Oracle's STANDARD_HASH:

import com.google.common.base.Charsets;
import com.google.common.hash.Hashing;
...

String input = "1234";        
String hash = Hashing.sha256()
       .hashString(input, Charsets.UTF_8)
       .toString()
       // toString() returns the HEX value as lower-case, whereas
       // Oracle's STANDARD_HASH returns an upper-cased string
       .toUpperCase(); 

System.out.println(hash);

This prints out 03AC674216F3E15C761EE1A5E255F067953623C8B388B4459E13F978D7C846F4 which is the same you get in Oracle with

select STANDARD_HASH('1234','SHA256') from dual;
Mick Mnemonic
  • 7,638
  • 2
  • 24
  • 30