Password hash

Storing password

Best practice for storing password is to never store plain password but hash value of password and its salt, so that when password storage is compromised, it is still considerably very difficult task to retrieve plain password.

Password hash algorithms are designed to make computation to retrieve actual password be expensive so that it is not feasible for attacker.

Password hash and verification

Fano Framework provides several password hash algorithm based on HashLib4Pascal and BCrypt libraries.

Fano Framework provides simple wrapper for these libraries through IPasswordHash interface.

Generate password hash

To generate password hash, you call hash() method of IPasswordHash interface. This method accepts string of plain password and returns hashed password as hexadecimal string.

var passwHash : IPasswordHash;
    plainPassw, hashedPassword : string;
...
plainPassw := 'PAssw0rd';
hashedPassword := passwHash.hash(plainPassw);

Verify plain password against password hash

To verify password against password hash, you call verify() method of IPasswordHash interface. This method accepts string of plain password and hashed password and returns boolean true when they match or false otherwise.

var passwHash : IPasswordHash;
    plainPassw, hashedPassword : string;
    verified : boolean;
...
plainPassw := 'PAssw0rd';
hashedPassword := 'edaadeaa....';
verified := passwHash.verify(plainPassw, hashedPassword);

Setting password hash parameters.

Before you generate password hash or verify a password, you need to set some parameters related to passworh hash implementation

Salt

To prevent against rainbow table attack, you should salt password. You should use random salt value. This value can be stored along with password hash.

To set salt, you call salt() method of IPasswordHash interface. This method returns current password hash instance.

passwHash.salt('some random value');

Cost

To make generating password expensive, some password hash algorithm requires you to set number of iterations as cost of algorithm. Higher value usually means higher computation resources. You should think carefully about this value as this is trade-off between security and performance.

To set cost, call cost() method with integer value for cost. This method returns current password hash instance.

passwHash.cost(1024);

Memory cost

Some algorithm employs memory cost, such as Argon2i. For other, this value is ignored.

To set memory cost, you call memory() method of IPasswordHash interface. This method returns current password hash instance.

passwHash.memory(32);

Paralleism

Some algorithm employs paralleism cost.

To set paralleism cost, you call paralleism() method of IPasswordHash interface. This method returns current password hash instance.

passwHash.paralleism(1);

Secret key

In addition to salt, some algorithm allows to use secret key which application must kept secret.

To set secret key, you call secret() method of IPasswordHash interface. This method returns current password hash instance.

passwHash.secret('hush hush value');

Password hash length

To set how many bytes passwod hash length, you set it using len() method and pass integer value of number of bytes of hash.

passwHash.len(64);

Available password hash implementations

Currently, Fano Framework provides IPasswordHash implementation for Argon2i, PBKDF2, Scrypt, BCrypt and SHA2.

PBKDF2 password hash

To use PBKDF2 password hash, you need to use TPbkdf2PasswordHash class. You can register this class with dependency container using its factory class TPbkdf2PasswordHashFactory.

To register password hash,

container.add('passwHash', TPbkdfPasswordHashFactory.create());

To retrieve password hash instance,

var passwHash : IPasswordHash;
passwHash := container['passwHash'] as IPasswordHash;

Argon2i password hash

To use Argon2i password hash, you need to use TArgon2iPasswordHash class. You can register this class with dependency container using its factory class TArgon2iPasswordHashFactory.

To register password hash,

container.add('passwHash', TArgon2iPasswordHashFactory.create());

See PBKDF2 code above to retrieve password hash instance.

You can set initial setting values for password hash instance, for example

container.add(
    'passwHash',
    TArgon2iPasswordHashFactory.create()
        .cost(4)
        .memory(32)
        .paralleism(4)
        .len(32)
);

Scrypt password hash

To use Scrypt password hash, you need to use TScryptPasswordHash class. You can register this class with dependency container using its factory class TScryptPasswordHashFactory.

To register password hash,

container.add('passwHash', TScryptPasswordHashFactory.create());

BCrypt password hash

To use BCrypt password hash, you need to use TBcryptPasswordHash class. You can register this class with dependency container using its factory class TBcryptPasswordHashFactory.

To register password hash,

container.add('passwHash', TBcryptPasswordHashFactory.create());

SHA2 password hash

While you are advised NOT to use SHA2 for password hash as they are not designed for hashing password, Fano Framework provides IPasswordHash implementation for SHA2 256 bit and 512 bit using TSHA2_256PasswordHash and TSHA2_512PasswordHash class.

You can register this class with dependency container using its factory class TSha2PasswordHashFactory.

To register SHA2 256 bit password hash,

container.add('passwHash', TSha2PasswordHashFactory.create().use256());

To register SHA2 512 bit password hash,

container.add('passwHash', TSha2PasswordHashFactory.create().use512());

Explore more