{"record":{"id":"0b49d00987053ebd","repo":"PHPOffice/PhpSpreadsheet","slug":"unsupported-encryption-algorithm","errorCode":null,"errorMessage":"Unsupported encryption algorithm","messagePattern":"Unsupported encryption algorithm","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Reader\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Reader/Xls.php","lineNumber":877,"sourceCode":"     * The decryption functions and objects used from here on in\n     * are based on the source of Spreadsheet-ParseExcel:\n     * https://metacpan.org/release/Spreadsheet-ParseExcel\n     */\n    protected function readFilepass(): void\n    {\n        $length = self::getUInt2d($this->data, $this->pos + 2);\n\n        if ($length < 54) {\n            throw new Exception('Unexpected file pass record length');\n        }\n\n        $recordData = $this->readRecordData($this->data, $this->pos + 4, $length);\n\n        // move stream pointer to next record\n        $this->pos += 4 + $length;\n\n        if (substr($recordData, 0, 2) !== \"\\x01\\x00\" || substr($recordData, 4, 2) !== \"\\x01\\x00\") {\n            throw new Exception('Unsupported encryption algorithm');\n        }\n        if (!$this->verifyPassword($this->encryptionPassword, substr($recordData, 6, 16), substr($recordData, 22, 16), substr($recordData, 38, 16), $this->md5Ctxt)) {\n            throw new Exception('Decryption password incorrect');\n        }\n\n        $this->encryption = self::MS_BIFF_CRYPTO_RC4;\n\n        // Decryption required from the record after next onwards\n        $this->encryptionStartPos = $this->pos + self::getUInt2d($this->data, $this->pos + 2);\n    }\n\n    /**\n     * Make an RC4 decryptor for the given block.\n     *\n     * @param int $block Block for which to create decrypto\n     * @param string $valContext MD5 context state\n     */\n    private function makeKey(int $block, string $valContext): Xls\\RC4","sourceCodeStart":859,"sourceCodeEnd":895,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Reader/Xls.php#L859-L895","documentation":"After reading a well-formed FILEPASS record, the Xls reader only supports standard RC4 encryption: the version words at offsets 0 and 4 of the record must both be 0x0001. Any other value (XOR obfuscation, AES / Enhanced Cryptographic Provider used by newer Excel or third-party encryptors) reaches this throw.","triggerScenarios":"Loading an RC4-encrypted workbook whose algorithm identifiers were rewritten by a non-Microsoft tool, an XOR-obfuscated file whose record happens to be padded past 54 bytes, or AES-encrypted .xls produced by Office 2007+ compatibility mode.","commonSituations":"Files encrypted with 'Microsoft Strong Cryptographic Provider' defaults, workbooks run through DRM/document-management systems, or legacy XOR encryption chosen by very old Excel versions.","solutions":["Decrypt the file outside PHP (LibreOffice headless convert, msoffice-crypt, or Excel itself) and load the plaintext copy","Re-save from Excel without encryption, or in .xlsx format with a reader-supported protection level","Check the file in Excel (File > Info) to see which encryption provider/algorithm was used, then re-encrypt with RC4 if in-file decryption must work"],"exampleFix":"// before\n$reader = new \\PhpOffice\\PhpSpreadsheet\\Reader\\Xls();\n$spreadsheet = $reader->load('aes-encrypted.xls'); // Unsupported encryption algorithm\n\n// after: convert to plaintext xlsx externally first\nshell_exec('soffice --headless --convert-to xlsx --outdir /tmp aes-encrypted.xls'); // supply password via macro/filter if needed\n$spreadsheet = IOFactory::load('/tmp/aes-encrypted.xlsx');","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    $spreadsheet = $reader->load($path);\n} catch (\\PhpOffice\\PhpSpreadsheet\\Reader\\Exception $e) {\n    if (str_contains($e->getMessage(), 'Unsupported encryption algorithm')) {\n        // decrypt externally (LibreOffice/msoffice tools) and retry on the plaintext copy\n    }\n}","preventionTips":["Standardize uploads on .xlsx to avoid legacy RC4/XOR variants","Document that only standard RC4-encrypted .xls is supported","Offer an out-of-band decryption step for AES-protected files"],"tags":["xls","encryption","rc4","aes","phpspreadsheet"],"backgroundTag":"unsupported-encryption-algorithm","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}