Skip to content
>_ TrueFileSize.com
·8 min read

Handling Password-Protected Archives

Password-protected archives are common in enterprise workflows — payroll exports, client deliverables, sensitive documents. Handling them in code requires choosing the right library, respecting encryption strength, and testing against real samples.

Three levels of ZIP encryption

  • ZipCrypto (legacy) — broken since 2001, breakable in minutes. Don't use.
  • AES-128 — strong, widely supported in modern tools
  • AES-256 — enterprise-grade; used by 7-Zip by default

ZIP with password in Node.js

Native zlib doesn't handle encryption. Use archiver-zip-encrypted for writing and adm-zip for reading:

import archiver from 'archiver';
import encrypted from 'archiver-zip-encrypted';

archiver.registerFormat('zip-encrypted', encrypted);

const output = fs.createWriteStream('secret.zip');
const archive = archiver.create('zip-encrypted', {
  zlib: { level: 9 },
  encryptionMethod: 'aes256',
  password: 'correct-horse-battery-staple',
});
archive.pipe(output);
archive.file('sensitive.pdf', { name: 'sensitive.pdf' });
await archive.finalize();

Reading password-protected ZIP

import AdmZip from 'adm-zip';

const zip = new AdmZip('secret.zip');
for (const entry of zip.getEntries()) {
  const buffer = entry.getData('correct-horse-battery-staple');
  fs.writeFileSync('/out/' + entry.entryName, buffer);
}

RAR and 7Z

Neither has a production-grade pure-JS library. Shell out to unrar or 7z:

import { execFile } from 'child_process';
import { promisify } from 'util';
const exec = promisify(execFile);

// RAR with password
await exec('unrar', ['x', '-p' + password, 'archive.rar', '/out/']);

// 7Z with password
await exec('7z', ['x', '-p' + password, 'archive.7z', '-o/out/']);

Test with our sample RAR and 7Z files.

Handling wrong passwords

try {
  const buffer = entry.getData(password);
} catch (err) {
  if (err.message.includes('password')) {
    return { error: 'Wrong password' };
  }
  throw err;
}

Brute-force protection

  • Limit password attempts per user to 3-5 per minute
  • Log failed attempts with IP for abuse detection
  • Reject passwords under 8 characters in upload validation
  • Use CAPTCHA after 3 failed decrypt attempts

Security notes

  • Never log passwords, even in debug mode. Redact or hash.
  • Passwords in memory: clear buffers after use where possible
  • ZipCrypto-encrypted files should be treated as plaintext for sensitive data
  • Don't accept uploads where the password is in the filename or metadata

Testing checklist

  • Correct password extracts cleanly
  • Wrong password returns clear error, not 500
  • Empty password handled gracefully
  • ZipCrypto-encrypted ZIP is either rejected or flagged as insecure
  • AES-256 7Z works via shell fallback
  • Rate limit triggers after N attempts

Related

For general ZIP handling, see server-side ZIP extraction.