How to Encrypt PDF Files in the Browser with Vue 3 and pdf-lib

sunshey

sunshey

2026-09-02T13:45:31Z

2 min read

Encrypting PDFs in the browser requires careful handling of passwords and encryption standards. Here's how to build a browser-based PDF encryption tool with Vue 3 and pdf-lib.

The challenge: Password management and security

PDF encryption involves:

  1. Generating secure encryption keys from passwords
  2. Supporting different encryption levels (128-bit, 256-bit)
  3. Setting document permissions (print, copy, modify)
  4. Ensuring compatibility with PDF readers

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, EncryptionOptions } from 'pdf-lib'

const file = ref<File | null>(null)
const password = ref('')
const confirmPassowrd = ref('')
const encryptionLevel = ref<128 | 256>(256)
const encrypting = ref(false)
const result = ref<Uint8Array | null>(null)

async function encryptPdf() {
  if (!file.value || !password.value) return
  if (password.value !== confirmPassowrd.value) {
    alert('Passwords do not match')
    return
  }

  encrypting.value = true

  const arrayBuffer = await file.value.arrayBuffer()
  const pdf = await PDFDocument.load(arrayBuffer)

  const encryptionOptions: EncryptionOptions = {
    ownerPassword: password.value,
    userPassword: password.value,
    permissions: {
      printing: 'highResolution',
      modifying: false,
      copying: false,
      annotating: false,
      fillingForms: false,
      contentAccessibility: false,
      documentAssembly: false,
    },
    encryption: encryptionLevel.value === 256 ? 'AES_256' : 'AES_128',
  }

  result.value = await pdf.save({
    encryption: encryptionOptions,
  })

  encrypting.value = false
}
</script>
Enter fullscreen mode Exit fullscreen mode

Key implementation details

1. Password validation

Ensure passwords match and meet minimum requirements:

if (password.value !== confirmPassowrd.value) {
  throw new Error('Passwords do not match')
}
if (password.value.length < 8) {
  throw new Error('Password must be at least 8 characters')
}
Enter fullscreen mode Exit fullscreen mode

2. Encryption level selection

pdf-lib supports both 128-bit and 256-bit encryption:

const encryption = encryptionLevel.value === 256 
  ? 'AES_256' 
  : 'AES_128'
Enter fullscreen mode Exit fullscreen mode

3. Permission settings

Control what recipients can do with the encrypted PDF:

permissions: {
  printing: 'highResolution',  // Allow high-res printing
  modifying: false,            // Prevent modifications
  copying: false,              // Prevent text extraction
  annotating: false,           // Prevent annotations
  fillingForms: false,         // Prevent form filling
  contentAccessibility: false, // Prevent screen reader access
  documentAssembly: false,     // Prevent document assembly
}
Enter fullscreen mode Exit fullscreen mode

4. Password strength feedback

Provide real-time feedback on password strength:

const passwordStrength = computed(() => {
  const pwd = password.value
  let strength = 0
  if (pwd.length >= 8) strength++
  if (/[A-Z]/.test(pwd)) strength++
  if (/[a-z]/.test(pwd)) strength++
  if (/[0-9]/.test(pwd)) strength++
  if (/[^A-Za-z0-9]/.test(pwd)) strength++
  return strength
})
Enter fullscreen mode Exit fullscreen mode

Limitations

No password recovery

If the password is lost, the PDF cannot be decrypted.

Solution: Always store passwords securely and provide clear warnings.

Browser memory

Very large PDFs may cause memory issues during encryption.

Solution: Process in smaller batches or use Web Workers.

Compatibility

Some older PDF readers don't support 256-bit encryption.

Solution: Offer 128-bit as a fallback option.

Summary

Building a browser-based PDF encryption tool involves:

  1. Loading the PDF with pdf-lib
  2. Validating password strength and confirmation
  3. Applying encryption with desired permissions
  4. Saving and downloading the encrypted PDF

Try it at en.sotool.top/encrypt.