phalcon/cphalcon · error · UnknownHashAlgorithm
Unknown hashing algorithm: {}
Error message
Unknown hashing algorithm: {} What it means
Security::computeHmac() wraps hash_hmac(): on PHP 8 an unknown algorithm throws ValueError, which Phalcon catches and rethrows as UnknownHashAlgorithm; additionally an empty/false HMAC result (PHP 7 behavior for unknown algorithms) triggers the same exception. The message interpolates the algorithm name: "Unknown hashing algorithm: {algo}".
Source
Thrown at phalcon/Encryption/Security.zep:273
* @param string $key
* @param string $algo
* @param bool $raw
*
* @return string
* @throws Exception
*/
public function computeHmac(
string data,
string key,
string algorithm,
bool raw = false
) -> string {
var hmac;
try {
let hmac = this->phpHashHmac(algorithm, data, key, raw);
} catch \ValueError {
throw new UnknownHashAlgorithm(algorithm);
}
if unlikely !hmac {
throw new UnknownHashAlgorithm(algorithm);
}
return hmac;
}
/**
* Removes the value of the CSRF token and key from session
*/
public function destroyToken() -> <static>
{
var session;
let session = this->getLocalService("session", "localSession");
View on GitHub (pinned to b7419de9cd)
Solutions
- Use canonical PHP names: 'md5', 'sha1', 'sha256', 'sha512' - and strip whitespace: trim($algo).
- Validate before calling: in_array($algo, hash_algos(), true) (case-sensitive list, so lowercase first).
- If the algorithm arrives from outside (config, headers), map external names to PHP names ('HS256' -> 'sha256') via a lookup table instead of passing them through.
Example fix
// before
$hmac = $security->computeHmac($payload, $key, 'sha-256'); // hyphenated -> throws
// after
$algo = 'sha256'; // canonical hash_algos() name
if (!in_array($algo, hash_algos(), true)) {
throw new \InvalidArgumentException('Unsupported HMAC algorithm');
}
$hmac = $security->computeHmac($payload, $key, $algo); Defensive patterns
Strategy: validation
Validate before calling
$algo = strtolower(trim($algorithm));
if (!in_array($algo, hash_algos(), true)) {
throw new \InvalidArgumentException("Unsupported hash algorithm '{$algorithm}'");
}
$hmac = $security->computeHmac($data, $key, $algo); Type guard
function isValidHashAlgorithm(string $algorithm): bool
{
return in_array(strtolower(trim($algorithm)), hash_algos(), true);
} Try / catch
try {
$hmac = $security->computeHmac($data, $key, $algo);
} catch (\Phalcon\Encryption\Security\Exceptions\UnknownHashAlgorithm $e) {
throw new \InvalidArgumentException('Unsupported HMAC algorithm: ' . $algo, 0, $e);
} Prevention
- Whitelist algorithms ('sha256', 'sha512') instead of accepting arbitrary strings from config or request headers.
- Map external algorithm names (JWT 'HS256' -> 'sha256') through a lookup table.
- Normalize with trim + strtolower before validating; hash_hmac accepts known names case-insensitively but your whitelist should not rely on that.
When it happens
Trigger: Calling $security->computeHmac($data, $key, 'sha2565') / 'md6' / 'haval typo' etc. - any string not in hash_algos(); also algorithms valid for hash() but not accepted by hash_hmac(). Values like 'SHA256' (uppercase) ARE valid since hash_hmac is case-insensitive for known names.
Common situations: Algorithm names pulled from configuration or user input and never validated; copy-pasted algorithm identifiers with invisible whitespace or wrong casing variants ('sha-256' with a hyphen is NOT a valid PHP name - it is 'sha256'); interop code copying algorithm names from other ecosystems (Node 'sha256' is fine, but JWT 'HS256' is not).
Related errors
- Hash does not match.
- The cookie's key should be at least 32 characters long. Curr
- No route matched the request.
- Class '{className}' is not an ADR Action.
- Invalid module definition for module '{moduleName}': The mod
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/c119acc1e2d4c097.
Report an issue: GitHub.