I want to be able to securely (1) create and (2) validate a PIN, typed by a user primarily in a mobile app. There is no 'typical' password, although there is another 2nd factor.
The starting point would be something based on OWASP standards for passwords:
- get salt_1 (send to user device)
- hash PIN on device using salt_1 and bcrypt
- send over HTTPS to backend
- get salt_2
- hash the received hash using salt_2 and bcrypt
- save resulting hash or compare against previously saved hash
Now, this scenario obviously has a limited viability and robustness due to low PIN entropy (4 digits), so typical approach for passwords requires at least some alterations.
My ideas for additional security measures would be:
- salts should be treated as secret and stored securely and separately from hashed PINs (as in this answer )? If yes, sending it, even briefly, to user device is compromising this security a lot? Can I do something more here?
- limiting retrials of PIN validation appears to be more crucial than with passwords
Is there any other approach or enhancements to existing approach that I should consider?
There are, obviously, at least 3 perspectives: backend leak, MITM and device leak and the last one is the one I am least confident with, but maybe I should leave this to the user if he "chooses" to compromise his device security?