{"record":{"id":"a1ac733c485105c6","repo":"PHPOffice/PhpSpreadsheet","slug":"unsupported-password-algorithm-algorithmname","errorCode":null,"errorMessage":"Unsupported password algorithm: $algorithmName","messagePattern":"Unsupported password algorithm: \\$algorithmName","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Shared/PasswordHasher.php","lineNumber":39,"sourceCode":"        // Mapping between algorithm name in Excel and algorithm name in PHP\n        $mapping = [\n            Protection::ALGORITHM_MD2 => 'md2',\n            Protection::ALGORITHM_MD4 => 'md4',\n            Protection::ALGORITHM_MD5 => 'md5',\n            Protection::ALGORITHM_SHA_1 => 'sha1',\n            Protection::ALGORITHM_SHA_256 => 'sha256',\n            Protection::ALGORITHM_SHA_384 => 'sha384',\n            Protection::ALGORITHM_SHA_512 => 'sha512',\n            Protection::ALGORITHM_RIPEMD_128 => 'ripemd128',\n            Protection::ALGORITHM_RIPEMD_160 => 'ripemd160',\n            Protection::ALGORITHM_WHIRLPOOL => 'whirlpool',\n        ];\n\n        if (array_key_exists($algorithmName, $mapping)) {\n            return $mapping[$algorithmName];\n        }\n\n        throw new SpException('Unsupported password algorithm: ' . $algorithmName);\n    }\n\n    /**\n     * Create a password hash from a given string.\n     *\n     * This method is based on the spec at:\n     * https://interoperability.blob.core.windows.net/files/MS-OFFCRYPTO/[MS-OFFCRYPTO].pdf\n     * 2.3.7.1 Binary Document Password Verifier Derivation Method 1\n     *\n     * It replaces a method based on the algorithm provided by\n     * Daniel Rentz of OpenOffice and the PEAR package\n     * Spreadsheet_Excel_Writer by Xavier Noguer <xnoguer@rezebra.com>.\n     *\n     * @param string $password Password to hash\n     */\n    private static function defaultHashPassword(string $password): string\n    {\n        $verifier = 0;","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Shared/PasswordHasher.php#L21-L57","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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()."],"exampleFix":"// before\n$hash = \\PhpOffice\\PhpSpreadsheet\\Shared\\PasswordHasher::hashPassword($pw, 'sha512');\n// Unsupported password algorithm: sha512\n\n// after\nuse PhpOffice\\PhpSpreadsheet\\Worksheet\\Protection;\n$hash = \\PhpOffice\\PhpSpreadsheet\\Shared\\PasswordHasher::hashPassword(\n    $pw,\n    Protection::ALGORITHM_SHA_512, // exact 'SHA-512'\n    $salt,\n    $spinCount\n);","handlingStrategy":"validation","validationCode":"use PhpOffice\\PhpSpreadsheet\\Worksheet\\Protection;\nconst SHEET_ALGOS = [\n    Protection::ALGORITHM_MD2, Protection::ALGORITHM_MD4, Protection::ALGORITHM_MD5,\n    Protection::ALGORITHM_SHA_1, Protection::ALGORITHM_SHA_256, Protection::ALGORITHM_SHA_384,\n    Protection::ALGORITHM_SHA_512, Protection::ALGORITHM_RIPEMD_128,\n    Protection::ALGORITHM_RIPEMD_160, Protection::ALGORITHM_WHIRLPOOL,\n];\nif ($algo !== '' && !in_array($algo, SHEET_ALGOS, true)) {\n    throw new InvalidArgumentException(\"Unsupported sheet-protection algorithm: $algo\");\n}\n$hash = PasswordHasher::hashPassword($pw, $algo, $salt, $spin);","typeGuard":"function validSheetAlgorithm(string $algo): ?string\n{\n    return in_array($algo, SHEET_ALGOS, true) ? $algo : null; // exact spec spelling or null\n}","tryCatchPattern":"try { $hash = PasswordHasher::hashPassword($pw, $algo); }\ncatch (\\PhpOffice\\PhpSpreadsheet\\Exception $e) {\n    if (str_contains($e->getMessage(), 'Unsupported password algorithm')) {\n        $hash = PasswordHasher::hashPassword($pw); // fall back to legacy default hash\n    } else { throw $e; }\n}","preventionTips":["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."],"tags":["password-hashing","validation","sheet-protection","phpspreadsheet"],"backgroundTag":"unsupported-algorithm","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}