Login  Register

Re: Validate password with PBKDF2

Posted by Francis on Jun 30, 2017; 9:07pm
URL: https://forum.world.st/Validate-password-with-PBKDF2-tp4952973p4953138.html

Ah-ha! You are right, the proper way to encrypt is with the salt and then prepend the salt.
Thanks
Francis

FIY
UUID new asByteArray
 does not give a ByteArray because UUID is a subclass of ByteArray and asByteArray returns self



Erik Stel wrote
Francis,

You're using an empty salt when creating the hash. Just prepending a random number does not add much security. Anyone knowing your solution will just prepend a random number. And creating only a few accounts in your system will probably reveal that information as well. A wrong-doer will just use a fake salt and will still be able to try a rainbow table attack.

Please use a real random value for the salt. And easiest would be to give it a fixed size.

(Don't have an image and/or code available, so this might lead to some pseudo code ;-)

To generate a safe password hash which you can store in your db, the following method. It creates a random number (your example of a UUID of 16 bytes) and uses that as a salt for the password hash. Both values are then concatenated and returned as a 'safe' password. This can be stored in your db.

generateSafePasswordHashFor: aPassword

    | salt passwordHash safePasswordHash |

    salt := UUID new asByteArray.
    passwordHash := PBKDF2 derivedKeyHashFunction: SHA256
                        password: aPassword
                        salt: salt
                        iterations: 3000
                        length: 16.
    safePasswordHash := salt, passwordHash
    ^safePasswordHash

To validate a user's password you retrieve the safePasswordHash from your db (based on the user's id) and validate the given password against it. For this the salt is retrieved from the safePasswordHash (first 16 bytes because UUID is 16 bytes) and it is then used to calculate the hash of the given password. It should match the second part of the safePasswordHash.

validatePassword: aPassword against: safePasswordHash 

    | salt passwordHash |

    salt := safePasswordHash first: 16.
    passwordHash := PBKDF2 derivedKeyHashFunction: SHA256
                        password: aPassword
                        salt: salt
                        iterations: 3000
                        length: 16.
    ^safePasswordHash endsWith: passwordHash

Hope this helps.

For real safety, please add some checks for valid values. Did we receive a valid password? Is the safePasswordHash the correct length (in this case 32 bytes)? You might consider using another salt generator than UUID.

Cheers,
Erik