I have a specific problem about hashing algorithms in Java. I have 2 clients, one running python and the other running Java (I know, I could solve everything by using just python but right now I almost need to use java).
The clients need to compare the inserted passwords in the same way (i.e.: if a PIN generates an hash on the java clients the same hash needs to be generated by the python client.
I read here: Iterative hashing returns different values in Python and Java
And studied the official docs here: https://docs.oracle.com/javase/7/docs/api/java/security/MessageDigest.html
And found out that python allows a seamless iterative encoding, while java does not. I tried to solve the problem using the .clone() method in the following way (java code):
// creation of SHA-1 instance:
MessageDigest message = MessageDigest.getInstance("SHA-1");
// construction of the string to hash:
String secretMessage = "0" + myPassWord + mySalt;
// updating the instance:
message.update(secretMessage.getBytes());
// cloning the instance:
MessageDigest messageClone = (MessageDigest) message.clone();
// digesting the clone: the result is of type byte[]:
byteResult = messageClone.digest();
// construction of the previousHash: this will be used in the
// next run of SHA-1 hashing. Python runs everything in lowercase.
// the hash is rendered as HEX characters String:
prevHash = (DatatypeConverter.printHexBinary(byteResult)).toLowerCase();
secretMessage = prevHash + "1" + myPassWord + mySalt;
message.update(secretMessage.getBytes());
// compute the final digest:
byteResult = message.digest();
// print it:
System.out.println(DatatypeConverter.printHexBinary(byteResult));
Now, by doing a System.out.println on the first iteration (index "0"), the hashes coincide.
Unfortunately, something wrong goes on the subsequent index and I can't, for the love of my, understand what is it. I suspect it's got something to do with how python converts strings and inserts it into the secretMessage variable.
For your information, here is the code in python:
digest2 = ""
for i in range (0, 2):
digest2 = sha1(digest2 + str(i) + password_to_hash + salt).hexdigest()
print digest2
The problem is that in the Java implementation, you feed the MessageDigest
first the iteration String, and then the second iteration String without resetting the MessageDigest
, so in effect it is creating a single hash of a String
like:
"0" + pw + salt + sha-of-data-so-far + "1" + pw + salt
The python implementation however starts a new hash for the second iteration and creates two hashes:
"0" + pw + salt
And then:
sha-of-iteration-1 + "1" + pw + salt