I Love Tools

ilovetools.net
Document Password Protector

Document Password Protector

AES-256-GCM encryption Β· Self‑decrypting output

Drag & drop your file here

or click to browse

Any file type supported

End-to-end encryption Β· Processed entirely in your browser

No data is ever uploaded Β· AES-256-GCM Β· PBKDF2

Encrypted Document

Enter the password to unlock

`; } function downloadFile(data, filename) { const blob = new Blob([data], { type: 'application/octet-stream' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } // ──────────────────────────────── // Extract package from self-decrypting HTML // ──────────────────────────────── async function extractPackageFromHTML(file) { const text = await file.text(); const startIdx = text.indexOf(BASE64_MARKER_START); if (startIdx === -1) return null; const contentStart = startIdx + BASE64_MARKER_START.length; const endIdx = text.indexOf(BASE64_MARKER_END, contentStart); if (endIdx === -1) return null; const base64 = text.substring(contentStart, endIdx); return base64ToUint8(base64); } // ──────────────────────────────── // Main process // ──────────────────────────────── async function processFile() { if (isProcessing || !selectedFile || !passwordInput.value) return; if (currentMode === 'encrypt' && passwordInput.value !== confirmPasswordInput.value) { showToast('Passwords do not match.', 'error'); appCard.style.animation = 'shake 0.5s ease-in-out'; setTimeout(() => appCard.style.animation = '', 500); return; } isProcessing = true; updateActionButtonState(); processingOverlay.classList.remove('hidden'); actionButton.classList.add('processing'); dropZone.style.pointerEvents = 'none'; const originalBtnText = btnText.textContent; btnText.textContent = currentMode === 'encrypt' ? 'Encrypting...' : 'Decrypting...'; try { if (currentMode === 'encrypt') { const packageBytes = await encryptFileData(selectedFile); const htmlContent = generateSelfDecryptingHTML(packageBytes); const outName = selectedFile.name + '.html'; downloadFile(htmlContent, outName); showToast(`βœ“ Encrypted! Saved as "${outName}". Open it to unlock.`, 'success', 6000); passwordInput.value = ''; confirmPasswordInput.value = ''; strengthMeter.classList.add('hidden'); passwordMatchMsg.classList.add('hidden'); } else { // Decrypt mode: try binary .dpp first, then HTML let packageBytes = null; const fileExt = selectedFile.name.split('.').pop().toLowerCase(); if (fileExt === 'html' || fileExt === 'htm') { packageBytes = await extractPackageFromHTML(selectedFile); if (!packageBytes) throw new Error('Could not find encrypted data inside the HTML file.'); } else { const buffer = await selectedFile.arrayBuffer(); packageBytes = new Uint8Array(buffer); } const result = await decryptPackage(packageBytes, passwordInput.value); downloadFile(result.data, result.filename); showToast(`βœ“ Decrypted! Original filename: "${result.filename}"`, 'success'); passwordInput.value = ''; } updateActionButtonState(); } catch (err) { showToast('βœ— ' + (err.message || 'Decryption failed.'), 'error', 7000); appCard.style.animation = 'shake 0.5s ease-in-out'; setTimeout(() => appCard.style.animation = '', 500); } finally { isProcessing = false; processingOverlay.classList.add('hidden'); actionButton.classList.remove('processing'); btnText.textContent = originalBtnText; dropZone.style.pointerEvents = 'auto'; updateActionButtonState(); } } window.processFile = processFile; // ──────────────────────────────── // Reset All function // ──────────────────────────────── function resetAll() { if (isProcessing) return; // Clear file selectedFile = null; fileInput.value = ''; dropZoneContent.classList.remove('hidden'); fileInfo.classList.add('hidden'); dropZone.classList.remove('has-file'); // Clear passwords passwordInput.value = ''; confirmPasswordInput.value = ''; strengthMeter.classList.add('hidden'); passwordMatchMsg.classList.add('hidden'); // Switch to encrypt tab switchTab('encrypt'); // Update button states updateActionButtonState(); updatePasswordStrength(); checkPasswordMatch(); } window.resetAll = resetAll; // Keyboard shortcut document.addEventListener('keydown', e => { if ((e.ctrlKey || e.metaKey) && e.key === 'Enter' && !actionButton.disabled && !isProcessing) { e.preventDefault(); processFile(); } if (e.key === 'Escape' && selectedFile && !isProcessing) { e.preventDefault(); clearFile(new Event('keydown')); } }); // Init updateActionButtonState(); })();
error: Sorry, stealing another person's content is not a good practice.
Scroll to Top