NAME
Crypt::Sodium::XS::OO::pwhash - Password hashing and verification
SYNOPSIS
use Crypt::Sodium::XS;
use Crypt::Sodium::XS::Util "sodium_random_bytes";
my $pwhash = Crypt::Sodium::XS->pwhash;
my $passphrase = "this is a passphrase.";
# key derivation
my $salt = sodium_random_bytes($pwhash->SALTBYTES);
my $key_size = 32;
my $key = $pwhash->pwhash($passphrase, $salt, $key_size);
# password storage
my $pwhash_str = $pwhash->str($passphrase);
die "bad password" unless $pwhash->verify($pwhash_str, $passphrase);
if ($pwhash->str_needs_rehash($pwhash_str)) {
my $new_pwhash_str = $pwhash->str($passphrase);
}
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.
Crypt::Sodium::XS::pwhash functions 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 output.
The same password hashed with different salts will produce different outputs.
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:
Password storage
Or rather: storing what it takes to verify a password without having to store the actual password.
Deriving a secret key from a password
For example, for disk encryption. Crypt::Sodium::XS::pwhash's high-level
pwhash_*
API currently leverages the Argon2id function on all platforms (when not using primitive-specific functions). This can change at any point in time, but it is guaranteed that a given version of libsodium can verify all hashes produced by all previous versions, from any platform. Applications don't have to worry about backward compatibility.
The scryptsalsa208sha256
primitive uses the more conservative and widely deployed Scrypt function.
CONSTRUCTOR
new
my $pwhash = Crypt::Sodium::XS::OO::pwhash->new(primitive => 'argon2id');
my $pwhash = Crypt::Sodium::XS->pwhash;
Returns a new onetimeauth object for the given primitive. If not given, the default primitive is default
.
ATTRIBUTES
primitive
my $primitive = $pwhash->primitive;
$pwhash->primitive('poly1305');
Gets or sets the primitive used for all operations by this object. Note this can be default
.
METHODS
primitives
my @primitives = Crypt::Sodium::XS::OO::pwhash->primitives;
my @primitives = $pwhash->primitives;
Returns a list of all supported primitive names, including default
.
Can be called as a class method.
PRIMITIVE
my $default_primitive = $pwhash->PRIMITIVE;
Returns the primitive used for all operations by this object. Note this will never be default
but would instead be the primitive it represents.
pwhash
my $hash
= $pwhash->pwhash($password, $salt, $hash_size, $opslimit, $memlimit);
$password
is an arbitrary-length input password. It may be a Crypt::Sodium::XS::MemVault.
$salt
is an arbitrary string which must be "SALTBYTES" bytes. It may be random and does not need to be kept secret.
$hash_size
is optional. It specifies the desired output hash size, in bytes. It must be in the range of "BYTES_MIN" to "BYTES_MAX", inclusive. If it is omitted or numifies to zero (undef, 0, ""), the default of "STRBYTES" will be used.
$opslimit
is optional. It specifies the cpu-hardness of generating the hash. It must be in the range of "OPSLIMIT_MIN" to "OPSLIMIT_MAX", inclusive. If it is omitted or numifies to zero (undef, 0, ""), the default of "OPSLIMIT_INTERACTIVE" will be used.
$memlimit
is optional. It specifies the memory-hardness of generating the hash. It must be in the range of "MEMLIMIT_MIN" to "MEMLIMIT_MAX", inclusive. If it is omitted or numifies to zero (undef, 0, ""), the default of "MEMLIMIT_INTERACTIVE" will be used.
Returns a Crypt::Sodium::XS::MemVault: the output hash of $hash_size
bytes.
salt
my $salt = $pwhash->salt;
Returns a random salt of "SALTBYTES" bytes.
str
my $hash_string = $pwhash->str($password, $opslimit, $memlimit);
$password
is an arbitrary-length input password. It may be a Crypt::Sodium::XS::MemVault.
$opslimit
is optional. It specifies the cpu-hardness of generating the hash. It must be in the range of "OPSLIMIT_MIN" to "OPSLIMIT_MAX", inclusive. If it is omitted or numifies to zero (undef, 0, ""), the default of "OPSLIMIT_INTERACTIVE" will be used.
$memlimit
is optional. It specifies the memory-hardness of generating the hash. It must be in the range of "MEMLIMIT_MIN" to "MEMLIMIT_MAX", inclusive. If it is omitted or numifies to zero (undef, 0, ""), the default of "MEMLIMIT_INTERACTIVE" will be used.
Returns an ASCII encoded string into out, which includes:
* the result of a memory-hard, CPU-intensive hash function applied to the password
* the automatically generated salt used for the previous computation
* the other parameters required to verify the password, including the algorithm identifier, its version, opslimit, and memlimit.
str_needs_rehash
my $needs_rehash
= $pwhash->str_needs_rehash($hash_string, $opslimit, $memlimit);
$hash_string
is a string returned by a previous call to "str".
$opslimit
is optional. It specifies the required cpu-hardness of generating the hash. It must be in the range of "OPSLIMIT_MIN" to "OPSLIMIT_MAX", inclusive. If it is omitted or numifies to zero (undef, 0, ""), the default of "OPSLIMIT_INTERACTIVE" will be used.
$memlimit
is optional. It specifies the required memory-hardness of generating the hash. It must be in the range of "MEMLIMIT_MIN" to "MEMLIMIT_MAX", inclusive. If it is omitted or numifies to zero (undef, 0, ""), the default of "MEMLIMIT_INTERACTIVE" will be used.
Returns false if $hash_str
is a valid password verification string (as generated by "str") and matches the parameters $opslimit
, $memlimit
, and the current primitive, true otherwise.
verify
my $is_valid = $pwhash->verify($hash_string, $password);
$hash_string
is a string returned by a previous call to "str".
$password
is an arbitrary-length input password. It may be a Crypt::Sodium::XS::MemVault.
Returns true if $hash_string
is a valid password verification string (as generated by "str") for $password
, false otherwise.
BYTES_MAX
my $hash_max_size = $pwhash->BYTES_MAX;
Returns the maximum size, in bytes, of hash output.
BYTES_MIN
my $hash_min_size = $pwhash->BYTES_MAX;
Returns the minimum size, in bytes, of hash output.
MEMLIMIT_INTERACTIVE
OPSLIMIT_INTERACTIVE
my $memlimit = $pwhash->MEMLIMIT_INTERACTIVE;
my $opslimit = $pwhash->OPSLIMIT_INTERACTIVE;
Returns baseline values for interactive online applications. This currently requires 64 MiB of dedicated RAM.
MEMLIMIT_MODERATE
OPSLIMIT_MODERATE
my $memlimit = $pwhash->MEMLIMIT_MODERATE;
my $opslimit = $pwhash->OPSLIMIT_MODERATE;
Returns baseline settings slightly higher than interactive. This requires 256 MiB of dedicated RAM and takes about 0.7 seconds on a 2.8 GHz Core i7 CPU.
MEMLIMIT_SENSITIVE
OPSLIMIT_SENSITIVE
my $memlimit = $pwhash->MEMLIMIT_SENSITIVE;
my $opslimit = $pwhash->OPSLIMIT_SENSITIVE;
Returns baseline settings for highly-sensitive and non-interactive sessions. With these parameters, deriving a key takes about 3.5 seconds on a 2.8 GHz Core i7 CPU and requires 1024 MiB of dedicated RAM.
MEMLIMIT_MAX
my $memlimit = $pwhash->MEMLIMIT_MAX;
Returns the maximum memlimit.
MEMLIMIT_MIN
my $memlimit = $pwhash->MEMLIMIT_MIN;
Returns the minimum memlimit.
OPSLIMIT_MAX
my $memlimit = $pwhash->OPSLIMIT_MAX;
Returns the maximum opslimit.
OPSLIMIT_MIN
my $memlimit = $pwhash->OPSLIMIT_MIN;
Returns the minimum opslimit.
PASSWD_MAX
my $hash_max_size = $pwhash->PASSWD_MAX;
Returns the maximum size, in bytes, of password input.
PASSWD_MIN
my $hash_min_size = $pwhash->PASSWD_MIN;
Returns the minimum size, in bytes, of password input.
SALTBYTES
my $salt_size = $pwhash->SALTBYTES;
Returns the size, in bytes, of a salt.
STRBYTES
my $hash_string_size = $pwhash->STRBYTES;
Returns the size, in bytes, of a string returned by "str".
STRPREFIX
my $hash_string_prefix = $pwhash->STRPREFIX;
Returns the primitive-specific prefix of a string returned by "str".
GUIDELINES FOR CHOOSING OPSLIMIT AND MEMLIMIT
Start by determining how much memory the function can use. What will be the highest number of processes evaluating the function simultaneously (ideally, no more than 1 per CPU core)? How much physical memory is guaranteed to be available?
Set memlimit to the amount of memory you want to reserve for password hashing.
Then set opslimit to 3 and measure the time it takes to hash a password.
If this is way too long for your application, reduce memlimit, but keep opslimit set to 3.
If the function is so fast that you can afford it to be more computationally intensive without any usability issues, then increase opslimit.
For online use (e.g. logging in on a website), a 1 second computation is likely to be the acceptable maximum.
For interactive use (e.g. a desktop application), a 5 second pause after having entered a password is acceptable if the password doesn’t need to be entered more than once per session.
For non-interactive and infrequent use (e.g. restoring an encrypted backup), an even slower computation can be an option.
However, the best defense against brute-force password cracking is to use strong passwords.
SEE ALSO
FEEDBACK
For reporting bugs, giving feedback, submitting patches, etc. please use the following:
RT queue at https://rt.cpan.org/Dist/Display.html?Name=Crypt-Sodium-XS
IRC channel
#sodium
onirc.perl.org
.Email the author directly.
AUTHOR
Brad Barden <perlmodules@5c30.org>
COPYRIGHT & LICENSE
Copyright (c) 2022 Brad Barden. All rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.