hash static method
Future<PasswordHashResult>
hash({
- required String password,
- PasswordAlgorithm algorithm = PasswordAlgorithm.argon2id,
- int saltLength = SaltGenerator.minimumLength,
- AlgorithmConfig? config,
- String? pepper,
- PepperProvider? pepperProvider,
override
Hashes password and returns a PasswordHashResult.
Parameters
password: The plaintext password to hash. Must not be empty.algorithm: Hashing algorithm. Defaults to PasswordAlgorithm.argon2id.saltLength: Salt length in bytes. Must be ≥ 16. Defaults to 16.config: Algorithm-specific configuration. Uses OWASP defaults if omitted.pepper: A raw pepper string to mix in. Mutually exclusive withpepperProvider.pepperProvider: A PepperProvider to fetch the pepper from.
Returns
A PasswordHashResult containing the self-contained encoded hash string. Only store PasswordHashResult.hash in your database.
Example
// Simple usage
final result = await PasswordGuard.hash(password: 'hunter2');
// With pepper from environment
final result = await PasswordGuard.hash(
password: 'hunter2',
pepperProvider: EnvPepperProvider(key: 'APP_PEPPER'),
);
// Custom config
final result = await PasswordGuard.hash(
password: 'hunter2',
config: Argon2Config(memory: 131072, iterations: 4),
);
Throws InvalidConfigurationException if config is invalid. Throws PepperException if pepper provider fails.
Implementation
static Future<PasswordHashResult> hash({
required String password,
PasswordAlgorithm algorithm = PasswordAlgorithm.argon2id,
int saltLength = SaltGenerator.minimumLength,
AlgorithmConfig? config,
String? pepper,
PepperProvider? pepperProvider,
}) async {
if (password.isEmpty) {
throw const InvalidConfigurationException('Password must not be empty.');
}
if (pepper != null && pepperProvider != null) {
throw const InvalidConfigurationException(
'Provide either "pepper" or "pepperProvider", not both.',
);
}
final resolvedConfig = config ?? algorithm.defaultConfig;
resolvedConfig.validate();
final salt = SaltGenerator.generate(length: saltLength);
// Resolve pepper
final String? resolvedPepper;
if (pepperProvider != null) {
resolvedPepper = await pepperProvider.getPepper();
} else {
resolvedPepper = pepper;
}
// Apply pepper to password if provided
final effectivePassword = resolvedPepper != null
? _applyPepper(password, resolvedPepper)
: password;
final hasher = _hashers[algorithm]!;
final rawHash = await hasher.hashRaw(
password: effectivePassword,
salt: salt,
config: resolvedConfig,
);
final encodedHash = HashParser.encode(
algorithm: algorithm,
config: resolvedConfig,
salt: salt,
hashValue: rawHash,
);
return PasswordHashResult(
hash: encodedHash,
salt: salt,
algorithm: algorithm,
createdAt: DateTime.now().toUtc(),
);
}