NAME

Crypt::NaCl::Sodium::pwhash - Password hashing (yescrypt)

VERSION

version 1.0.8.0

SYNOPSIS

use Crypt::NaCl::Sodium qw( :utils );

my $crypto_pwhash = Crypt::NaCl::Sodium->pwhash();

my ($salt, $key, $hashed, $password);

# Some simple password vulnerable to dictionary attack
$password = "letmein1";

## Key derivation
########

# generate salt
$salt = $crypto_pwhash->salt();

# can be used later in other methods as the actual key
$key = $crypto_pwhash->key( $password, $salt, bytes => 32 );

## Password storage
########

# save this in database as hash of user password
$hashed = $crypto_pwhash->str( $password );

DESCRIPTION

Secret keys used to encrypt or sign confidential data have to be chosen from a very large keyspace. However, passwords are usually short, human-generated strings, making dictionary attacks practical.

The crypto_pwhash provides methods to derive a secret key of any size from a password and a salt.

  • The generated key has the size defined by the application, no matter what the password length is.

  • The same password hashed with same parameters will always produce the same key.

  • The same password hashed with different salts will produce different keys.

  • The function deriving a key from a password and a salt is CPU intensive and intentionally requires a fair amount of memory. Therefore, it mitigates brute-force attacks by requiring a significant effort to verify each password.

Common use cases:

  • Protecting an on-disk secret key with a password,

  • Password storage, or rather: storing what it takes to verify a password without having to store the actual password.

METHODS

salt

my $salt = $crypto_pwhash->salt();

Helper method to generate a random salt to be used by "key".

The length of the $salt equals "SALTBYTES".

Returns Data::BytesLocker object.

key

my $key = $crypto_pwhash->key( $password, $salt,
    bytes => $bytes, opslimit => $opslimit, memlimit => $memlimit
);

Derive an $bytes long key from a password $password and salt $salt by performing a maximum of $opslimit number of computations and using up to $memlimit amount of RAM.

The optional $bytes parameter specifies the output length of the $key and has the default value of "STRBYTES".

The optional $opslimit represents a maximum amount of computations to perform. Raising this number will make the function require more CPU cycles to compute a key. Default value is "OPSLIMIT_INTERACTIVE".

The optional $memlimit is the maximum amount of RAM that the function will use, in bytes. It is highly recommended to allow the function to use at least 16 megabytes. Default value is "MEMLIMIT_INTERACTIVE".

NOTE: For interactive sessions, "OPSLIMIT_INTERACTIVE" and "MEMLIMIT_INTERACTIVE" provide a safe base line for these two parameters. However, using higher values may improve security.

For highly sensitive data, "OPSLIMIT_SENSITIVE" and "MEMLIMIT_SENSITIVE" can be used as an alternative. But with these parameters, deriving a key takes more than 10 seconds on a 2.8 Ghz Core i7 CPU and requires up to 1 gigabyte of dedicated RAM.

Keep in mind that in order to produce the same $key that is $bytes long from the same $password, the same $salt, and the same values for $opslimit and $memlimit have to be used. Therefore, these parameters have to be stored for each user.

The length of the $key equals the value of $bytes.

Returns Data::BytesLocker object.

str

my $hashed = $crypto_pwhash->str( $password,
    opslimit => $opslimit, memlimit => $memlimit
);

Returns ASCI encoded string, which includes:

  • the result of a memory-hard, CPU-intensive hash function applied to the password $password

  • the automatically generated salt used for the previous computation

  • the other parameters required to verify the password: $opslimit and $memlimit

The output string is zero-terminated, includes only ASCII characters and can be conveniently stored into SQL databases and other data stores. No additional information has to be stored in order to verify the password.

For the description of the optional $opslimit and $memlimit please refer to the "key".

The length of the $hashed equals STRBYTES.

Returns Data::BytesLocker object.

verify

if ( $crypto_pwhash->verify($hashed, $password) ) {
    # password is correct
}

Verify that the $hashed password verification string (as generated by "str") matches the password $password.

Returns true if they match, false otherwise.

NOTE: If $hashed is "STRBYTES" long, it is required that it is zero-terminated (last character of the string is a null byte). This function however also accepts $hashed which is STRBYTES - 1 long.

CONSTANTS

SALTBYTES

my $salt_length = $crypto_pwhash->SALTBYTES;

Returns the length of salt.

STRBYTES

my $hashed_length = $crypto_pwhash->STRBYTES;

Returns the length of password verification string.

OPSLIMIT_INTERACTIVE

my $opslimit_interactive = $crypto_pwhash->OPSLIMIT_INTERACTIVE;

Returns a value which represents the default maximum amount of computations to perform.

MEMLIMIT_INTERACTIVE

my $memlimit_interactive = $crypto_pwhash->MEMLIMIT_INTERACTIVE;

Returns a value which represents the maximum amount of RAM to use, in bytes.

OPSLIMIT_SENSITIVE

my $opslimit_sensitive = $crypto_pwhash->OPSLIMIT_SENSITIVE;

Returns a value which represents the suggested for highly sensitive data amount of computations to perform.

MEMLIMIT_SENSITIVE

my $memlimit_sensitive = $crypto_pwhash->MEMLIMIT_SENSITIVE;

Returns a value which represents the suggested for highly sensitive data amount of RAM to use, in bytes.

ALGORITHM DETAILS

crypto_pwhash uses yescrypt key derivation algorithm, which has been submitted to the Password Hashing Competition.

SEE ALSO

AUTHOR

Alex J. G. Burzyński <ajgb@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2015 by Alex J. G. Burzyński <ajgb@cpan.org>.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.