·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.