Java calculate hex representation of a SHA-1 digest of a String
If you don't want to add any extra dependencies to your project, you could also use
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(message.getBytes("utf8"));
byte[] digestBytes = digest.digest();
String digestStr = javax.xml.bind.DatatypeConverter.printHexBinary(digestBytes);
Using apache common codec library:
DigestUtils.sha1Hex("aff")
The result is 0c05aa56405c447e6678b7f3127febde5c3a9238
That's it :)
This is happening because cript.digest() returns a byte array, which you're trying to print out as a character String. You want to convert it to a printable Hex String.
Easy solution: Use Apache's commons-codec library:
String password = new String(Hex.encodeHex(cript.digest()),
CharSet.forName("UTF-8"));
One iteration of a hash algorithm is not secure. It's too fast. You need to perform key strengthening by iterating the hash many times.
Furthermore, you are not salting the password. This creates a vulnerability to pre-computed dictionaries, like "rainbow tables."
Instead of trying to roll your own code (or using some sketchy third-party bloatware) to do this correctly, you can use code built-in to the Java runtime. See this answer for details.
Once you have hashed the password correctly, you'll have a byte[]
. An easy way to convert this to a hexadecimal String
is with the BigInteger
class:
String passwordHash = new BigInteger(1, cript.digest()).toString(16);
If you want to make sure that your string always has 40 characters, you may need to do some padding with zeroes on the left (you could do this with String.format()
.)