hash_hmac_algos
Returns the list of hashing algorithms that are valid for use with hash_hmac.
hash_hmac_algos(): array- Added in PHP 7.2.0
Return value
arrayA numerically indexed array of algorithm names suitable for use with hash_hmac().
Errors
Nothing.
hash_hmac_algos() returns the subset of hash_algos() that hash_hmac() and hash_hmac_file() will actually accept. PHP 7.2 removed the non-cryptographic algorithms from that set, because an HMAC built on a checksum like CRC-32 provides no security at all.
When to reach for it
Use it to validate an algorithm name before signing or verifying, especially when the name arrives from configuration, a database column, or a protocol header. Passing an unsupported name to hash_hmac() throws a ValueError in PHP 8, so a cheap membership check turns a fatal error into a controlled response.
It is also the right list to show in an admin panel when an operator picks a signing algorithm — offering crc32b there would produce a runtime failure the moment it was selected.
What trips people up
Do not validate against hash_algos() and assume the name will work for HMAC; that list is strictly larger and includes crc32b, adler32, the FNV family, MurmurHash3 and xxHash. Conversely, do not assume every entry here is a good choice: md5 and sha1 are present for compatibility with older protocols, but sha256 should be your default for new work.
Example
When to use it
- Validate a signing algorithm from config before calling hash_hmac().
- Populate a dropdown of signing algorithms in an admin settings page.
- Decide at runtime whether a server supports the algorithm a partner API requires.
Frequently asked questions
What is the difference between hash_algos and hash_hmac_algos?
hash_hmac_algos() is the smaller list, containing only cryptographic algorithms. PHP 7.2 removed adler32, crc32, crc32b and the FNV family from HMAC use, and PHP 8.0 made passing them a ValueError.
Which algorithm should I pass to hash_hmac?
Use sha256 unless a third-party protocol requires something else. sha1 and md5 remain in the list only for compatibility with older APIs.
Do I need hash_hmac_algos if I hardcode sha256?
No. It only earns its place when the algorithm name is dynamic — from config, a database, or a request header.
More examples
Guarding a configured algorithm
Only the sha256 call produces a signature. The other two return a readable message instead of throwing a ValueError, which is what you want when the algorithm name comes from a config file.
<?php
function sign(string $algo, string $data, string $key): string {
if (!in_array($algo, hash_hmac_algos(), true)) {
return "cannot sign with '$algo'";
}
return hash_hmac($algo, $data, $key);
}
echo sign('sha256', 'payload', 'k'), PHP_EOL;
echo sign('crc32b', 'payload', 'k'), PHP_EOL;
echo sign('md6', 'payload', 'k'), PHP_EOL;Which algorithms were excluded
The excluded list is made up of checksums and fast non-cryptographic hashes. The final check shows sha1 is still permitted for HMAC — HMAC-SHA1 remains usable for legacy protocols even though plain sha1() is weak.
<?php
$excluded = array_values(array_diff(hash_algos(), hash_hmac_algos()));
echo count($excluded), ' algorithms are not allowed for HMAC', PHP_EOL;
foreach (array_slice($excluded, 0, 8) as $a) {
echo ' - ', $a, PHP_EOL;
}
var_dump(in_array('sha1', hash_hmac_algos(), true));
Discussion