/** * DOCX Agile Encryption (MS-OFFCRYPTO) * * Implements ECMA-376 Agile Encryption (used by Office 2010+) for encrypted * DOCX files. Encrypted DOCX files use the CFB (Compound File Binary) format * to wrap the ZIP content. * * This module provides: * - Password-based encryption/decryption of DOCX content * - EncryptionInfo XML generation/parsing * * All AES and SHA primitives are delegated to `@utils/crypto`, which uses * synchronous `node:crypto` APIs in Node and Web Crypto in the browser. * The KDF inner loop runs ~100,000 hashes per derived key; on Node we go * through the synchronous fast path so a round-trip completes in well * under a second instead of the multi-second microtask churn that the * old `await crypto.subtle.digest()` loop produced. * * References: * - MS-OFFCRYPTO: Office Document Cryptography Structure * - ECMA-376 Part 3: Markup Compatibility and Extensibility */ /** Agile encryption parameters. */ export interface AgileEncryptionInfo { /** Cipher algorithm (AES). */ readonly cipherAlgorithm: "AES"; /** Cipher chaining mode. */ readonly cipherChaining: "ChainingModeCBC"; /** Key bit length (128, 192, 256). */ readonly keyBits: 128 | 192 | 256; /** Hash algorithm. */ readonly hashAlgorithm: "SHA1" | "SHA256" | "SHA384" | "SHA512"; /** Hash output size in bytes. */ readonly hashSize: number; /** Number of iterations (spin count). */ readonly spinCount: number; /** Salt for key derivation (16 bytes). */ readonly keySalt: Uint8Array; /** Encrypted verifier hash input. */ readonly encryptedVerifierHashInput: Uint8Array; /** Encrypted verifier hash value. */ readonly encryptedVerifierHashValue: Uint8Array; /** Encrypted key value. */ readonly encryptedKeyValue: Uint8Array; /** Block size (16 for AES). */ readonly blockSize: number; /** Data integrity salt. */ readonly dataIntegritySalt?: Uint8Array; /** Data integrity HMAC value. */ readonly dataIntegrityHmac?: Uint8Array; } /** Detect whether a buffer is an encrypted Office document (CFB format). */ export declare function isEncryptedDocx(buffer: Uint8Array): boolean; /** * Derive an encryption key from a password using the agile encryption KDF. * * Per MS-OFFCRYPTO 2.3.4.11: * H_0 = H(salt + password) * H_i = H(iterator + H_{i-1}) for i = 0..spinCount-1 * H_final = H(H_{spinCount} + blockKey) * Key = first keySize bytes of H_final */ export declare function deriveEncryptionKey(password: string, info: { keySalt: Uint8Array; spinCount: number; hashAlgorithm: string; keyBits: number; }, blockKey: Uint8Array): Promise; /** Block keys as defined in MS-OFFCRYPTO 2.3.4.13. */ export declare const AGILE_BLOCK_KEYS: { /** For encrypting verifier hash input. */ readonly verifierHashInput: Uint8Array; /** For encrypting verifier hash value. */ readonly verifierHashValue: Uint8Array; /** For encrypting the main key. */ readonly encryptedKey: Uint8Array; /** For data integrity HMAC key. */ readonly dataIntegrityKey: Uint8Array; /** For data integrity HMAC value. */ readonly dataIntegrityValue: Uint8Array; }; /** * Verify a password against the encryption info. * * @returns True if password is correct. */ export declare function verifyPassword(password: string, info: AgileEncryptionInfo): Promise; /** * Decrypt the package data using the password. * * @param encryptedPackage - The EncryptedPackage stream from CFB. * @param info - Agile encryption parameters. * @param password - The user password. * @param maxDecryptedSize - Optional upper bound on the decrypted size; if the * `totalSize` header claims a larger value, throw rather than allocate. * Defaults to 512 MiB so adversarial files cannot trigger arbitrary-size * allocations before security policy is applied at the unzip layer. * @returns The decrypted (unencrypted) package bytes. */ export declare function decryptPackage(encryptedPackage: Uint8Array, info: AgileEncryptionInfo, password: string, maxDecryptedSize?: number): Promise; /** * Parse an EncryptionInfo XML stream from a CFB-wrapped encrypted DOCX. * * This is the UTF-8 XML part after the 8-byte version/flags header. * * @param xmlStr - The EncryptionInfo XML content. * @returns Parsed agile encryption info. */ export declare function parseEncryptionInfoXml(xmlStr: string): AgileEncryptionInfo; /** * Read an encrypted DOCX file by providing a password. * * Handles the full pipeline: * 1. Parse CFB container * 2. Extract EncryptionInfo and EncryptedPackage streams * 3. Verify password and decrypt * 4. Return the decrypted DOCX ZIP bytes * * @param buffer - The encrypted DOCX file (CFB format). * @param password - The password to decrypt with. * @param maxDecryptedSize - Optional cap on the decrypted size (defaults to 512 MiB). * @returns The decrypted DOCX ZIP bytes (can be passed to readDocx). * @throws Error if the file is not encrypted, password is wrong, or decryption fails. */ export declare function decryptDocx(buffer: Uint8Array, password: string, maxDecryptedSize?: number): Promise; /** Options for DOCX encryption. */ export interface EncryptOptions { /** Key length in bits. Default: 256. */ readonly keyBits?: 128 | 192 | 256; /** Hash algorithm. Default: SHA512. */ readonly hashAlgorithm?: "SHA1" | "SHA256" | "SHA384" | "SHA512"; /** Number of KDF iterations (spin count). Default: 100000. */ readonly spinCount?: number; } /** * Encrypt a DOCX ZIP file with a password using Agile Encryption (MS-OFFCRYPTO). * * Produces a CFB (OLE2 Compound File) containing: * - EncryptionInfo stream (Agile encryption XML) * - EncryptedPackage stream (segment-encrypted ZIP data) * * The output can be opened by Microsoft Word with the given password. * * @param zipBytes - The unencrypted DOCX content (ZIP format). * @param password - The password to encrypt with. * @param options - Encryption options (key length, hash algorithm, spin count). * @returns The encrypted DOCX as a CFB-formatted Uint8Array. */ export declare function encryptDocx(zipBytes: Uint8Array, password: string, options?: EncryptOptions): Promise;