PDF encryption is essential for protecting sensitive documents, but implementing it correctly requires understanding two types of passwords and encryption algorithms.
Here’s how to build a browser-based PDF encryption tool with Vue 3 and pdf-lib.
The challenge: Two passwords, one PDF
PDF encryption isn’t just about setting a password. It involves:
- User password: Required to open the document
- Owner password: Controls permissions (printing, copying, editing)
- Encryption algorithm: AES-128 or AES-256
The stack
- Vue 3 with Composition API
- pdf-lib for PDF manipulation
- Vite for bundling
The core implementation
<script setup lang="ts">
import { ref } from 'vue'
import { PDFDocument, StandardPermissions } from 'pdf-lib'
const file = ref<File | null>(null)
const userPassword = ref('')
const ownerPassword = ref('')
const encryptionStrength = ref<'AES_128' | 'AES_256'>('AES_256')
const encrypting = ref(false)
const encryptedPdf = ref<Uint8Array | null>(null)
async function encryptPdf() {
if (!file.value || !userPassword.value) return
encrypting.value = true
const arrayBuffer = await file.value.arrayBuffer()
const pdf = await PDFDocument.load(arrayBuffer)
const bytes = await pdf.save({
userPassword: userPassword.value,
ownerPassword: ownerPassword.value || undefined,
permissions: StandardPermissions.Print | StandardPermissions.Copy,
encryption: {
standard: encryptionStrength.value
}
})
encryptedPdf.value = bytes
encrypting.value = false
}
</script>
Enter fullscreen mode Exit fullscreen mode
Key implementation details
1. Password handling
The user password is required, but the owner password is optional:
const bytes = await pdf.save({
userPassword: userPassword.value, // Required
ownerPassword: ownerPassword.value || undefined, // Optional
// ...
})
Enter fullscreen mode Exit fullscreen mode
2. Permission control
pdf-lib provides standard permissions:
import { StandardPermissions } from 'pdf-lib'
const permissions =
StandardPermissions.Print | // Allow printing
StandardPermissions.Copy | // Allow text copying
StandardPermissions.Modify | // Allow modifications
StandardPermissions.Annotate // Allow form filling
Enter fullscreen mode Exit fullscreen mode
3. Encryption strength
Choose between AES-128 and AES-256:
const bytes = await pdf.save({
// ...
encryption: {
standard: 'AES_256' // or 'AES_128'
}
})
Enter fullscreen mode Exit fullscreen mode
AES-256 is recommended for sensitive documents.
4. Error handling
Handle common errors:
try {
const bytes = await pdf.save({ /* ... */ })
} catch (error) {
if (error.message.includes('password')) {
// Password validation error
} else if (error.message.includes('memory')) {
// Insufficient memory
}
}
Enter fullscreen mode Exit fullscreen mode
Limitations
Large files
Very large PDFs may cause memory issues in the browser.
Solution: Process in chunks or use Web Workers.
Password complexity
The tool can’t enforce password strength, but you can add client-side validation:
function isValidPassword(password: string): boolean {
return password.length >= 8 &&
/[A-Z]/.test(password) &&
/[a-z]/.test(password) &&
/[0-9]/.test(password)
}
Enter fullscreen mode Exit fullscreen mode
Summary
Building a browser-based PDF encryption tool involves:
- Loading the PDF with pdf-lib
- Setting user and owner passwords
- Configuring permissions
- Choosing encryption strength
- Saving with encryption enabled
Try it at en.sotool.top/encrypt.