PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Reader\Exception

Unsupported encryption algorithm

Error message

Unsupported encryption algorithm

What it means

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.

Source

Thrown at src/PhpSpreadsheet/Reader/Xls.php:877

     * The decryption functions and objects used from here on in
     * are based on the source of Spreadsheet-ParseExcel:
     * https://metacpan.org/release/Spreadsheet-ParseExcel
     */
    protected function readFilepass(): void
    {
        $length = self::getUInt2d($this->data, $this->pos + 2);

        if ($length < 54) {
            throw new Exception('Unexpected file pass record length');
        }

        $recordData = $this->readRecordData($this->data, $this->pos + 4, $length);

        // move stream pointer to next record
        $this->pos += 4 + $length;

        if (substr($recordData, 0, 2) !== "\x01\x00" || substr($recordData, 4, 2) !== "\x01\x00") {
            throw new Exception('Unsupported encryption algorithm');
        }
        if (!$this->verifyPassword($this->encryptionPassword, substr($recordData, 6, 16), substr($recordData, 22, 16), substr($recordData, 38, 16), $this->md5Ctxt)) {
            throw new Exception('Decryption password incorrect');
        }

        $this->encryption = self::MS_BIFF_CRYPTO_RC4;

        // Decryption required from the record after next onwards
        $this->encryptionStartPos = $this->pos + self::getUInt2d($this->data, $this->pos + 2);
    }

    /**
     * Make an RC4 decryptor for the given block.
     *
     * @param int $block Block for which to create decrypto
     * @param string $valContext MD5 context state
     */
    private function makeKey(int $block, string $valContext): Xls\RC4

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Decrypt the file outside PHP (LibreOffice headless convert, msoffice-crypt, or Excel itself) and load the plaintext copy
  2. Re-save from Excel without encryption, or in .xlsx format with a reader-supported protection level
  3. 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

Example fix

// before
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
$spreadsheet = $reader->load('aes-encrypted.xls'); // Unsupported encryption algorithm

// after: convert to plaintext xlsx externally first
shell_exec('soffice --headless --convert-to xlsx --outdir /tmp aes-encrypted.xls'); // supply password via macro/filter if needed
$spreadsheet = IOFactory::load('/tmp/aes-encrypted.xlsx');
Defensive patterns

Strategy: try-catch

Try / catch

try {
    $spreadsheet = $reader->load($path);
} catch (\PhpOffice\PhpSpreadsheet\Reader\Exception $e) {
    if (str_contains($e->getMessage(), 'Unsupported encryption algorithm')) {
        // decrypt externally (LibreOffice/msoffice tools) and retry on the plaintext copy
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17). Data as JSON: /api/errors/0b49d00987053ebd. Report an issue: GitHub.