views:

102

answers:

3

By looking around here as well as the internet in general, I have found Bouncy Castle. I want to use Bouncy Castle (or some other freely available utility) to generate a SHA-256 Hash of a String in Java. Looking at their documentation I can't seem to find any good examples of what I want to do. Can anybody here help me out?

+4  A: 

If all you want to do is hash a string, I'd just use the built-in MessageDigest class.

MessageDigest md = MessageDigest.getInstance("SHA-256");
String text = "This is some text";

md.update(text.getBytes("UTF-8")); // Change this to "UTF-16" if needed
byte[] digest = md.digest();

Tada, digest now contains the hash of your string.

Brendan Long
Does that compile? It seems like you would need a `text.getBytes()` in there somewhere..?
ladenedge
Text.getBytes() will use the platform default encoding. Bad idea.
Jon Skeet
@Jon Skeet, how about this then?
Brendan Long
@Brendan: Yes, that's better. The platform default encoding is almost *never* the right thing to do.
Jon Skeet
For the same plaintext, does the hash suppose to be different every time? Because that is what happening to me
Harry Pham
@Harry Pham, the hash should always be the same, but without more information it would be hard to say why you are getting different ones. You should probably open a new question.
Brendan Long
@Harry Pham: After calling `digest` the internal state is reset; so when you call it again without updating before, you get the hash of the empty string.
Debilski
+3  A: 

When using hashcodes with any jce provider you first try to get an instance of the algorithm, then update it with the data you want to be hashed and when you are finished you call digest to get the hash value.

MessageDigest sha = MessageDigest.getInstance("SHA-256");
sha.update(in.getBytes());
byte[] digest = sha.digest();

you can use the digest to get a base64 or hex encoded version according to your needs

Nikolaus Gradwohl
Out of curiosity, can you go straight to `digest()` with the input byte array, skipping `update()`?
ladenedge
One thing I noticed is that this works with "SHA-256" whereas "SHA256" throws a NoSuchAlgorithmException. No biggie.
npsken
As per my comment to Brandon, **do not** use `String.getBytes()` without specifying an encoding. Currently this code can give different results on different platforms - which is broken behaviour for a well-defined hash.
Jon Skeet
@ladenedge yes - if your string is short enought@KPthunder your right @Jon Skeet depends on the content of the string - but yes add an encoding string getBytes to be on the save side
Nikolaus Gradwohl
How to hex encode?
Eno
+4  A: 

This is already implemented in the runtim libs

public static String calc(InputStream is ) {
        String output;
        int read;
        byte[] buffer = new byte[8192];

        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256"); //"MD5");
            while ((read = is.read(buffer)) > 0) {
                digest.update(buffer, 0, read);
            }
            byte[] hash = digest.digest();
            BigInteger bigInt = new BigInteger(1, hash);
            output = bigInt.toString(16);

        } 
        catch (Exception e) {
            e.printStackTrace( System.err );
            return null;
        }
        return output;
    }
stacker