Whatever message this page gives is out now! Go check it out!
PasswordHashGenerate() creates a secure hash from a plaintext password.PasswordHashVerify() verifies a plaintext password against a stored hash.PasswordHashVerify().PasswordHashGenerate() to hash API tokens, service account credentials, or any sensitive string that needs one-way storage.PasswordHashGenerate() and PasswordHashVerify() functions.| Parameter | Type | Default | Valid range | Description |
|---|---|---|---|---|
SALTLENGTH | Integer | 16 | 1 to 1024 | Length of the randomly generated salt, in bytes |
HASHLENGTH | Integer | 32 | 4 to 1024 | Length of the output hash, in bytes |
PARALLEL | Integer | 1 | 1 to 128 | Number of parallel threads used during hashing |
MEMORYCOST | Integer | 4096 | 4096 to 4 MB | Amount of memory used during hashing, in kilobytes (default is approximately 64 MB) |
CPUCOST | Integer | 3 | 1 to 1000 | Number of iterations (time cost) |
$argon2id$v=19$m=65536,t=3,p=1$<base64-salt>$<base64-hash>PasswordHashVerify() can verify it without you needing to remember the original parameters.| Parameter | Type | Default | Valid range | Description |
|---|---|---|---|---|
ROUNDS | Integer | 10 | 4 to 31 | Cost factor. The algorithm performs 2^rounds iterations. |
VERSION | String | "$2a" | "$2a", "$2b", "$2y" | BCrypt version identifier |
| Parameter | Type | Default | Valid range | Description |
|---|---|---|---|---|
SALTLENGTH | Integer | 16 | 1 to 1024 | Length of the randomly generated salt, in bytes |
KEYLENGTH | Integer | 32 | 1 to 1024 | Length of the output key, in bytes |
PARALLEL | Integer | 1 | 1 to 128 | Parallelization parameter (p) |
MEMORYCOST | Integer | 8 | Greater than 1, must be a power of 2, maximum 65536 1 to 256 | Block size parameter (r) |
CPUCOST | Integer | 16384 | 1-256 | CPU cost parameter (N) |
CPUCOST): 8 or higherMEMORYCOST): 16384 or higherPARALLEL): 1| Feature | Argon2 | BCrypt | SCrypt |
|---|---|---|---|
| OWASP recommendation | First choice | Acceptable alternative | Acceptable alternative |
| Memory-hard | Yes | No | Yes |
| Side-channel resistant | Yes (Argon2id) | No | No |
| GPU/ASIC resistant | Yes | Moderate | Yes |
| Configurable memory | Yes | No | Yes |
| Password length limit | None | 72 bytes | None |
| Best for | New applications | Legacy compatibility | Resource-constrained environments |
PasswordHashGenerate(password)
PasswordHashGenerate(password, algorithm)
PasswordHashGenerate(password, algorithm, options)| Parameter | Type | Required | Description |
|---|---|---|---|
password | String | Yes | The plaintext password to hash |
algorithm | String | No | The hashing algorithm: "Argon2" (default), "BCrypt", or "SCrypt" |
options | Struct | No | Algorithm-specific configuration. If omitted, secure defaults are used. |
hash = PasswordHashGenerate("mySecurePassword");PasswordHashVerify(password, hash)
PasswordHashVerify(password, hash, algorithm)| Parameter | Type | Required | Description |
|---|---|---|---|
password | String | Yes | The plaintext password to verify |
hash | String | Yes | The stored hash to verify against |
algorithm | String | No | The algorithm used to generate the hash: "Argon2", "BCrypt", or "SCrypt" |
true if the password matches the hash; false otherwise.isValid = PasswordHashVerify("mySecurePassword", storedHash, "Argon2");| Deprecated function | Replacement |
|---|---|
GenerateBCryptHash(password) | PasswordHashGenerate(password, "BCrypt") |
VerifyBCryptHash(password, hash) | PasswordHashVerify(password, hash, "BCrypt") |
GenerateSCryptHash(password) | PasswordHashGenerate(password, "SCrypt") |
VerifySCryptHash(password, hash) | PasswordHashVerify(password, hash, "SCrypt") |
// Hash generated with the old function
oldHash = GenerateBCryptHash("myPassword");
// Verified with the new function
isValid = PasswordHashVerify("myPassword", oldHash, "BCrypt");
// Returns: true// Hash generated with the new function
newHash = PasswordHashGenerate("myPassword", "BCrypt");
// Verified with the old function
isValid = VerifyBCryptHash("myPassword", newHash);
// Returns: truePasswordHashGenerate() with just the password string. This uses Argon2 with secure defaults (64 MB memory, 3 iterations, parallelism of 1).password = "userPassword123";
hash = PasswordHashGenerate(password);
// Example output:
// $argon2id$v=19$m=4096,t=3,p=1$cGZyNTFaNDNPaEs1TUt4Sw$CVGQlN+9KRV85Q2jOIVfmw// Argon2 (default)
argon2Hash = PasswordHashGenerate(password, "Argon2");
// BCrypt
bcryptHash = PasswordHashGenerate(password, "BCrypt");
// SCrypt
scryptHash = PasswordHashGenerate(password, "SCrypt");password = "userPassword123";
options = {
SALTLENGTH : 16,
HASHLENGTH : 32,
PARALLEL : 1,
MEMORYCOST : 65536,
CPUCOST : 3
};
hash = PasswordHashGenerate(password, "Argon2", options);password = "userPassword123";
options = {
ROUNDS : 12,
VERSION : "$2a"
};
hash = PasswordHashGenerate(password, "BCrypt", options);password = "userPassword123";
options = {
SALTLENGTH : 16,
KEYLENGTH : 32,
PARALLEL : 1,
MEMORYCOST : 16384,
CPUCOST : 8
};
hash = PasswordHashGenerate(password, "SCrypt", options);PasswordHashVerify() with the plaintext password and the stored hash:password = "userPassword123";
storedHash = "$argon2id$v=19$m=65536,t=3,p=1$...";
isValid = PasswordHashVerify(password, storedHash, "Argon2");
if (isValid) {
writeOutput("Password is correct.");
} else {
writeOutput("Invalid password.");
}options = {
ROUNDS : 12,
VERSION : "$2a"
};
isValid = PasswordHashVerify(password, storedHash, "BCrypt", options);<cfscript>
submittedEmail = form.email;
submittedPassword = form.password;
// Hash the password with Argon2 defaults
passwordHash = PasswordHashGenerate(submittedPassword);
// Store the user and hash in the database
queryExecute("
INSERT INTO users (email, password_hash, created_at)
VALUES (:email, :passwordHash, :createdAt)
", {
email : submittedEmail,
passwordHash : passwordHash,
createdAt : now()
});
writeOutput("Account created successfully.");
</cfscript><cfscript>
submittedEmail = form.email;
submittedPassword = form.password;
// Retrieve user from the database
qUser = queryExecute("
SELECT user_id, email, password_hash
FROM users
WHERE email = :email
", {
email : submittedEmail
});
if (qUser.recordCount eq 1) {
// Verify the submitted password against the stored hash
isValid = PasswordHashVerify(submittedPassword, qUser.password_hash, "Argon2");
if (isValid) {
session.userId = qUser.user_id;
session.isLoggedIn = true;
location(url="/dashboard", addtoken=false);
} else {
variables.errorMessage = "Invalid email or password.";
}
} else {
variables.errorMessage = "Invalid email or password.";
}
</cfscript><cfscript>
submittedPassword = form.password;
qUser = queryExecute("
SELECT user_id, password_hash, hash_algorithm
FROM users
WHERE email = :email
", {
email : form.email
});
if (qUser.recordCount eq 1) {
currentAlgorithm = qUser.hash_algorithm;
isValid = PasswordHashVerify(submittedPassword, qUser.password_hash, currentAlgorithm);
if (isValid) {
// If the user is still on BCrypt or SCrypt, upgrade to Argon2
if (currentAlgorithm neq "Argon2") {
newHash = PasswordHashGenerate(submittedPassword, "Argon2");
queryExecute("
UPDATE users
SET password_hash = :newHash,
hash_algorithm = :algo,
updated_at = :updatedAt
WHERE user_id = :userId
", {
newHash : newHash,
algo : "Argon2",
updatedAt : now(),
userId : qUser.user_id
});
}
session.userId = qUser.user_id;
session.isLoggedIn = true;
location(url="/dashboard", addtoken=false);
} else {
variables.errorMessage = "Invalid email or password.";
}
} else {
variables.errorMessage = "Invalid email or password.";
}
</cfscript><cfscript>
// High-security Argon2 configuration
options = {
MEMORYCOST : 524288, // 512 MB of memory
CPUCOST : 5, // 5 iterations
PARALLEL : 2 // 2 threads
};
hash = PasswordHashGenerate(password, "Argon2", options);
</cfscript><cfscript>
// High-security BCrypt configuration
options = {
ROUNDS : 14 // 2^14 = 16384 iterations
};
hash = PasswordHashGenerate(password, "BCrypt", options);
</cfscript><cfscript>
apiToken = createUUID() & "-" & createUUID();
tokenHash = PasswordHashGenerate(apiToken, "Argon2");
// Store tokenHash in the database
// When the client sends the token, verify it:
isValid = PasswordHashVerify(submittedToken, tokenHash, "Argon2");
</cfscript>PasswordHashGenerate() and PasswordHashVerify() are thread-safe. You can call them from multiple concurrent requests without synchronization.<cfscript>
passwords = ["pass1", "pass2", "pass3", "pass4", "pass5"];
for (pwd in passwords) {
thread name="hash_#pwd#" password=pwd {
hash = PasswordHashGenerate(attributes.password, "Argon2");
writeLog(text="Hashed: #hash#", file="hashing");
}
}
</cfscript>hash = GenerateBCryptHash(password);
isValid = VerifyBCryptHash(password, hash);hash = PasswordHashGenerate(password, "BCrypt");
isValid = PasswordHashVerify(password, hash, "BCrypt");hash = GenerateSCryptHash(password);
isValid = VerifySCryptHash(password, hash);hash = PasswordHashGenerate(password, "SCrypt");
isValid = PasswordHashVerify(password, hash, "SCrypt");// New registrations use Argon2
hash = PasswordHashGenerate(password);
// or explicitly:
hash = PasswordHashGenerate(password, "Argon2");options.ROUNDS = 12 and options.ROUNDS = "12" are both valid.options.ROUNDS = "twelve" throws an error: "The value twelve cannot be converted to a number."options.ROUNDS = null uses the default value without throwing an error.| Condition | Error message |
|---|---|
| Salt length out of range | "Invalid Argon2 hash format or parameters: Salt length must be >= 1 and <= 1024" |
| Hash length out of range | "Invalid Argon2 hash format or parameters: Hash length must be >= 4 and <= 1024" |
| Parallelism out of range | "Invalid Argon2 hash format or parameters: Parallelism must be >= 1 and <= 128" |
| Memory cost out of range | "Invalid Argon2 hash format or parameters: Memory cost must be >= 8 and <= 4194304" |
| CPU cost out of range | "Invalid Argon2 hash format or parameters: CPU cost must be >= 1 and <= 1000" |
| Condition | Error message |
|---|---|
| Rounds out of range | "Invalid BCrypt hash format or parameters: Rounds must be >= 4 and <= 31" |
| Condition | Error message |
|---|---|
| Salt length out of range | "Invalid SCrypt hash format or parameters: Salt length must be >= 1 and <= 1024" |
| Key length out of range | "Invalid SCrypt hash format or parameters: Key length must be >= 1 and <= 1024" |
| Parallelism out of range | "Invalid SCrypt hash format or parameters: Parallelization must be >= 1 and <= 128" |
| Memory cost out of range | "Invalid SCrypt hash format or parameters: CPU cost must be > 1, a power of 2, and <= 65536" |
| CPU cost invalid | "Invalid SCrypt hash format or parameters: Memory cost must be >= 1 and <= 256" |
false or throws a descriptive error, depending on the format mismatch:// Generated with Argon2
hash = PasswordHashGenerate("password", "Argon2");
// Verified with BCrypt: returns false or throws an error
isValid = PasswordHashVerify("password", hash, "BCrypt");<cfscript>
try {
hash = PasswordHashGenerate(form.password, "Argon2", options);
} catch (any e) {
writeLog(type="error", text="Password hashing failed: #e.message#", file="security");
variables.errorMessage = "An error occurred. Try again.";
}
</cfscript>| Scenario | Threshold |
|---|---|
| 100 Argon2 hashes (default settings) | Under 1 second total |
| 50 BCrypt hashes (default settings) | Under 1 second total |
| 100 SCrypt hashes (default settings) | Under 1 second total |
| 30 mixed-algorithm hashes | Under 10 seconds total |
MEMORYCOST parameter controls how much memory each hash computation requires. With the default of 4 MB, each concurrent hashing operation allocates approximately 64 MB of memory. On a server handling many concurrent login requests, memory consumption can be significant.Peak memory = MEMORYCOST (KB) x concurrent hashing requestsMEMORYCOST while increasing CPUCOST to reduce memory pressure while maintaining security.MEMORYCOST and CPUCOST to make each hash harder to crack.MEMORYCOST to very high values (for example, 4194304 KB, or 4 GB) or CPUCOST to 1000 will cause hashing to take an extremely long time and may result in OutOfMemoryError. Test your chosen parameters under realistic load before deploying to production.PasswordHashGenerate() and PasswordHashVerify() for all password hashing. These two functions replace the older per-algorithm functions and support Argon2, BCrypt, and SCrypt through a single API.