PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
Unsupported password algorithm: $algorithmName
Error message
Unsupported password algorithm: $algorithmName
What it means
Thrown by PasswordHasher::getAlgorithm() when the algorithm name passed to hashPassword() is non-empty but not one of the ten exact Excel algorithm identifiers (MD2, MD4, MD5, SHA-1, SHA-256, SHA-384, SHA-512, RIPEMD-128, RIPEMD-160, WHIRLPOOL — the Protection::ALGORITHM_* values). The lookup is an exact, case-sensitive array-key match, so near-misses are rejected.
Source
Thrown at src/PhpSpreadsheet/Shared/PasswordHasher.php:39
// Mapping between algorithm name in Excel and algorithm name in PHP
$mapping = [
Protection::ALGORITHM_MD2 => 'md2',
Protection::ALGORITHM_MD4 => 'md4',
Protection::ALGORITHM_MD5 => 'md5',
Protection::ALGORITHM_SHA_1 => 'sha1',
Protection::ALGORITHM_SHA_256 => 'sha256',
Protection::ALGORITHM_SHA_384 => 'sha384',
Protection::ALGORITHM_SHA_512 => 'sha512',
Protection::ALGORITHM_RIPEMD_128 => 'ripemd128',
Protection::ALGORITHM_RIPEMD_160 => 'ripemd160',
Protection::ALGORITHM_WHIRLPOOL => 'whirlpool',
];
if (array_key_exists($algorithmName, $mapping)) {
return $mapping[$algorithmName];
}
throw new SpException('Unsupported password algorithm: ' . $algorithmName);
}
/**
* Create a password hash from a given string.
*
* This method is based on the spec at:
* https://interoperability.blob.core.windows.net/files/MS-OFFCRYPTO/[MS-OFFCRYPTO].pdf
* 2.3.7.1 Binary Document Password Verifier Derivation Method 1
*
* It replaces a method based on the algorithm provided by
* Daniel Rentz of OpenOffice and the PEAR package
* Spreadsheet_Excel_Writer by Xavier Noguer <xnoguer@rezebra.com>.
*
* @param string $password Password to hash
*/
private static function defaultHashPassword(string $password): string
{
$verifier = 0;View on GitHub (pinned to 65b080eef4)
Solutions
- Use the constants, never literals: pass Protection::ALGORITHM_SHA_512 etc. from PhpOffice\PhpSpreadsheet\Worksheet\Protection.
- Normalize before calling: validate input against the ten known values (case-sensitive) and reject early with a clear message.
- If you only need Excel's legacy 16-bit hash, pass '' (the default) so getAlgorithm short-circuits to the default path.
- When the name comes from a file you parse, map it through a whitelist table keyed by the exact spec strings before invoking hashPassword().
Example fix
// before
$hash = \PhpOffice\PhpSpreadsheet\Shared\PasswordHasher::hashPassword($pw, 'sha512');
// Unsupported password algorithm: sha512
// after
use PhpOffice\PhpSpreadsheet\Worksheet\Protection;
$hash = \PhpOffice\PhpSpreadsheet\Shared\PasswordHasher::hashPassword(
$pw,
Protection::ALGORITHM_SHA_512, // exact 'SHA-512'
$salt,
$spinCount
); Defensive patterns
Strategy: validation
Validate before calling
use PhpOffice\PhpSpreadsheet\Worksheet\Protection;
const SHEET_ALGOS = [
Protection::ALGORITHM_MD2, Protection::ALGORITHM_MD4, Protection::ALGORITHM_MD5,
Protection::ALGORITHM_SHA_1, Protection::ALGORITHM_SHA_256, Protection::ALGORITHM_SHA_384,
Protection::ALGORITHM_SHA_512, Protection::ALGORITHM_RIPEMD_128,
Protection::ALGORITHM_RIPEMD_160, Protection::ALGORITHM_WHIRLPOOL,
];
if ($algo !== '' && !in_array($algo, SHEET_ALGOS, true)) {
throw new InvalidArgumentException("Unsupported sheet-protection algorithm: $algo");
}
$hash = PasswordHasher::hashPassword($pw, $algo, $salt, $spin); Type guard
function validSheetAlgorithm(string $algo): ?string
{
return in_array($algo, SHEET_ALGOS, true) ? $algo : null; // exact spec spelling or null
} Try / catch
try { $hash = PasswordHasher::hashPassword($pw, $algo); }
catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
if (str_contains($e->getMessage(), 'Unsupported password algorithm')) {
$hash = PasswordHasher::hashPassword($pw); // fall back to legacy default hash
} else { throw $e; }
} Prevention
- Only pass Protection::ALGORITHM_* constants — never hand-typed or PHP hash() names.
- Remember the empty-string algorithm is valid and selects the legacy Excel hash.
- When algorithm names come from XML/DB, normalize/whitelist them at the boundary.
When it happens
Trigger: Calling PasswordHasher::hashPassword($pw, $algorithm) with e.g. 'sha512' (lowercase), 'SHA512' (missing hyphen), 'bcrypt', or a raw string from a spreadsheet's own XML where you expected the library's constant spelling; an empty string is special-cased to the legacy default hash, so only non-empty unknown names throw.
Common situations: Copying algorithm names from sheetProtection XML attributes with altered casing; passing PHP hash() names ('ripemd160' works by luck, 'sha-512' doesn't); reading algorithm names from user/DB input; version drift where older code stored different spellings.
Related errors
- Password exceeds 255 characters
- Invalid R1C1-format Cell Reference
- Invalid A1-format Cell Reference
- File doesn't seem to be an OLE container.
- The filename $filename is not recognised as an OLE file
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/a1ac733c485105c6.
Report an issue: GitHub.