Tuesday, 21 January 2020

Password Hashing

Delphi is great for all kinds of software development from Windows based applications to web sites and mobile apps, but one area that it seems to be weak is with hashing of passwords. I cannot find any components built in or 3rd party that really do what was easy to do with Visual Studio (C#), here is what I would like to do:

  1. Find a modern hashing algorithm PKBDF2 or Argon2. 
  2. Must allow hash to be salted and the salt to be different every-time.
  3. Allow for the number of iterations to be specified.
  4. Previously I have also store a version number with the hash, this would also be a useful option.
  5. Validation should not require the original salt. Some solutions (one well known 3rd party company) says that you store the hash of the password and the salt in the database. 
  6. Works with existing Javascript hashing solutions e.g. CryptoJS, I imagine once the same parameters are applied it should work so that the hash can be created in Javascript and the validation can be done by Delphi.
Does anyone no of any 3rd party components that do password hashing well?

10 comments:

  1. TMS Cryptography Pack wouldn't do this?
    (Disclaimer, I haven't used it, but am looking at their all access package)

    ReplyDelete
    Replies
    1. With TMS you also need to store the salt. So when a user enters the password you hash it with the previous salt and compare the hash values. In Visual Studio you can have different salt values that produce different hash value but the validation matches them (PKBDF2).

      Delete
    2. I don't see how it would be possible to validate the hashed salted password without the salt. There seems to be something fundamentally broken if you are able to accomplish that task. You typically store the cleartext username, hashed password, and cleartext salt. Your salt can/should be unique per user. The salt should be cryptographically secure random data and not overly short. If you want to be overly secure, store the salt in a separate location than the username and hash. Certainly don't have one salt value for the entire database as that would dramatically reduce it's value. I haven't used TMS components, but from the face of it they seem fine. SecureBlackBox.com has the 'best' Delphi components for security, and StreamSec would be a runner up. I just purchased a TMS all-access license and I will be testing their cipher set soon and plan on using it.

      Specifically, PKDBF2 is calculated as: DK = PBKDF2(PRF, Password, Salt, c, dkLen) One character difference in salt should produce a completely unintellible/uncomparable derived key result....there should be no way to compare two hashes with different salts.

      Delete
  2. https://github.com/Xor-el/HashLib4Pascal

    ReplyDelete
  3. https://bitbucket.org/sergworks/tforge/downloads/

    ReplyDelete
  4. Check TSynSigner.PBKDF2 in https://github.com/synopse/mORMot/blob/master/SynCrypto.pas#L2050
    This supports SHA-1, SHA-256, SHA-384, SHA-512, SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHA3-S128, SHA3-S256 as internal hashing algorithm, and it is the fastest implementation in Delphi AFAIK.

    ReplyDelete
  5. Try Bcrypt for Delphi or Scrypt for Delphi
    https://github.com/JackTrapper/bcrypt-for-delphi
    https://github.com/JackTrapper/scrypt-for-delphi

    ReplyDelete
    Replies
    1. I can recommend this bcrypt library too. Bcrypt is a standard solution for this task and the library is working without a problem for our systems.

      Delete
    2. Yes BCrypt does seem to do what I am after. Thanks

      Delete
  6. By definition, salt could be known and stored within the DB, e.g. as 'salt|hashedpassword'. It just should be genuine, even better associated with a timestamp and an expiration time.

    ReplyDelete