Can I make a password check by comparing two hashed string inputfields?

8
I would like to make a password check for users that would like to change their passwords. I want to have two hashed string inputfields where a user can enter his new password twice. Than, those two hashed string fields have to be compared to each other. The password can only be saved if both hashed stringfields are the same. Is this possible in Microflow or Java? It would be even better to include a third inputfield where the user has to enter his initial password which has to be checked to the password in the database. Would that be possible as well?
asked
3 answers
12

Comparing hashed values is not the way to go. Comparing values of a HashString attribute in microflow will compare the hashed values indeed. But you cannot rely on them.

Why does the way of implementing your password check like Johan or Jasper told seem to 'work' now (i.e. <=2.4.2)? Well, when using non-salted password hashing algorithms like MD5, SHA, or SHA256 the hashing of a single password will always produce the same result. Besides the convenience of being able to compare those, using these algorithms also pose a security risk, because it's far more easy to crack those (predictable/comparable) hashes, and find the original passwords, e.g. using rainbow tables.

Mendix 2.4.3 introduces the ability to change the default used hashing algorithm for already running projects, as well as a bunch of salted hashing algorithms, which are far more resistant to brute-force cracking of the passwords.

The 'salt' I was talking about is (if you don't want to read the wikipedia link) a method of adding lots of randomness to the hashed value, while still being able to verify if the original password matches with the hash string. E.g. a SSHA hash of the word 'password' can be '{SSHA}SQOsLCJ4P0wEqpdEHf1w1fLMSu8Z/EQD' or '{SSHA}7iMg9yif3NnECFJaTMcBoZbduTD1Ghyq', while there are even more possible matching hashstrings than grains of sand in the Sahara.

Both a change of default hash algorithm, as well as the usage of a salted password hashing algorithm will render comparing previously hashed values useless.

So, about the answer to your question...

Yes, you can use a field where the user has to enter his/her old password, along with two temporary fields for entering the new password. Just do not compare the hashed values (which will be done in microflow by default), but use the unhashed values, which will be available until the object is committed. For doing this, you have to use two API methods available in Java code:

The MendixHashString object has a method 'getUnhashedValue()' which will return the non-hashed value of the attribute (which is only available before the first time the object gets committed from now on). Be careful with that value, and only use it to feed it to the 'verifyValue(String)' function of another MendixHashString object, and respect the privacy of your users. (!)

Using the verifyValue function of the MendixHashString object, you can verify whether the entered value matches with a hashed value, whatever algorithm is being used for this specific HashString. Be sure to ditch the contents of the temporary fields before committing the object.

P.S. I thorougly recommend using the HashString type for the temporary field, because the text typed by the user will only be available for a short time, until the object is committed. So, even when due to an exception, rollback, or a misconfiguration in your microflow the value would be committed to the database, before you would be able to erase the fields again, still no plaintext readable password would be present, but only hashed garbage!

answered
5

You can do that in Java, there you can retrieve the hashed password. I think the best way to do that is to add the two additional fields, newPassword1 and newPassword2
in a java action you should check if those two fields match if they don't show an error message If both fields match you can check if the hash is different from the original password field.
The code will look something like this:

IMendixObject userObject = userParam.getMendixObject();
String oriPassword = userObject.getValue("Password");
String newPassword1 = userObject.getValue("newPassword1");
String newPassword2 = userObject.getValue("newPassword2");

if( newPassword1 == null ) 
   throw new CoreException("You did not enter your password.");
if( newPassword2 == null ) 
   throw new CoreException("You did not confirm your password.");
if( !newPassword1.equals(newPassword2) )
   throw new CoreException("The passwords you have entered did not match.");

if( newPassword1.equals( oriPassword )  )
  throw new CoreException("The new password is equal to the old password.");

return true;
answered
5

It is not possible to compare HashString attributes in Microflow without using Java.

You can compare two HashString value's to each other using a before commit Microflow. This Microflow should have a Java action activity calling a custom Java action. In this action you can compare the values of the attributes with each other.

Wiki entry on Java programming for Mendix applications

answered