I find myself in a need to change website platforms from Java to PHP but I\'d like to keep all my user\'s passwords...
I had this code do the password hashing prior
What I normally do with Java to compute a SHA-1 hash that is exactly identical to the PHP sha1() function is the following. The key is that toHexString is used to show the raw bytes in a printable way. If you use the PHP function and want to obtain the same result of your convoluted process, you need to use the parameter $raw_output to true in PHP to get the raw bytes and apply Base64. Full source code.
/**
* Compute a SHA-1 hash of a String argument
*
* @param arg the UTF-8 String to encode
* @return the sha1 hash as a string.
*/
public static String computeSha1OfString(String arg) {
try {
return computeSha1OfByteArray(arg.getBytes(("UTF-8")));
} catch (UnsupportedEncodingException ex) {
throw new UnsupportedOperationException(ex);
}
}
private static String computeSha1OfByteArray(byte[] arg) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(arg);
byte[] res = md.digest();
return toHexString(res);
} catch (NoSuchAlgorithmException ex) {
throw new UnsupportedOperationException(ex);
}
}
private static String toHexString(byte[] v) {
StringBuilder sb = new StringBuilder(v.length * 2);
for (int i = 0; i < v.length; i++) {
int b = v[i] & 0xFF;
sb.append(HEX_DIGITS.charAt(b >>> 4)).append(HEX_DIGITS.charAt(b & 0xF));
}
return sb.toString();
}
[B@14e1f2b
is definitely not a hash. It's a result of implicit conversion from byte[]
to String
.
It looks like you do something like this:
String decodedHash = Base64().decode(hash); // Produces [B@14e1f2b
However, the correct representation of the hash is a byte array:
byte[] decodedHash = Base64().decode(hash);
PHP's sha1() encodes each byte of the output as hexadecimal by default, but you can get the raw output by passing true
as the second argument:
$digest = sha1($password, true); // This returns the same string of bytes as md.digest()
Then pass the digest to base64_encode and you are done:
base64_encode(sha1($password, true));
This returns the exact same SHA-1 hash as your java code.