How to Encrypt and Decrypt a PDF File with JavaScript

A PDF file can be encrypted, for security, in which case a password is needed to view or edit the contents. Dynamsoft Document Viewer is a JavaScript SDK for document scanning and viewing, which can encrypt and decrypt a PDF file. In this article, we are going to explore how to use it.

Use Dynamsoft Document Viewer to Open a PDF File

  1. Create a new HTML file with the following template.

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
      <title>Browse Viewer</title>
      <style>
      </style>
    </head>
    <body>
    </body>
    <script>
    </script>
    </html>
    
  2. Include Dynamsoft Document Viewer’s files.

    <script src="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@2.1.0/dist/ddv.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@2.1.0/dist/ddv.css">
    
  3. Initialize Dynamsoft Document Viewer with a license. You can apply for one here.

    Dynamsoft.DDV.Core.license = "LICENSE-KEY"; 
    Dynamsoft.DDV.Core.engineResourcePath = "https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@2.1.0/dist/engine";// Lead to a folder containing the distributed WASM files
    await Dynamsoft.DDV.Core.init();
    
  4. Create a new document instance.

    const docManager = Dynamsoft.DDV.documentManager;
    const doc = docManager.createDocument();
    
  5. Create an instance of browse viewer, bind it to a container and use it to view the document we just created.

    HTML:

    <div id="viewer"></div>
    

    JavaScript:

    const browseViewer = new Dynamsoft.DDV.BrowseViewer({
      container: document.getElementById("viewer"),
    });
    
    browseViewer.openDocument(doc.uid);
    

    CSS:

    #viewer {
      width: 320px;
      height: 480px;
    }
    
  6. Use input to select a PDF file and load it into the document instance so that we can use the browse viewer to view the file.

    HTML:

    <label>
      Select a PDF file to load:
      <br/>
      <input type="file" id="files" name="files" accept=".pdf" onchange="filesSelected()"/>
    </label>
    

    JavaScript:

    async function filesSelected(){
      let filesInput = document.getElementById("files");
      let files = filesInput.files;
      if (files.length>0) {
        const file = files[0];
        const blob = await readFileAsBlob(file);
        await doc.loadSource(blob); // load the PDF file
      }
    }
    
    function readFileAsBlob(file){
      return new Promise((resolve, reject) => {
        const fileReader = new FileReader();
        fileReader.onload = async function(e){
          const response = await fetch(e.target.result);
          const blob = await response.blob();
          resolve(blob);
        };
        fileReader.onerror = function () {
          reject('oops, something went wrong.');
        };
        fileReader.readAsDataURL(file); 
      })
    }
    

Open a Password-Protected PDF

If the PDF is password-protected, it will fail to open the PDF and throw an error, which indicates that we need to enter a password to open it.

Error: Failed to read the PDF file because it's encrypted and the correct password is not provided.

We can catch the error and ask the user to enter a password.

HTML:

<div class="modal input-modal">
  <div>
    <label>
      Please input the password:
    </label>
    <br/>
    <input type="password" id="password"/>
    <br/>
    <button id="okayBtn">Okay</button>
  </div>
</div>

CSS:

.modal {
  display: flex;
  align-items: flex-start;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  min-width: 250px;
  border: 1px solid gray;
  border-radius: 5px;
  background: white;
  z-index: 9999;
  padding: 10px;
  visibility: hidden;
}

.input-modal.active {
  visibility: inherit;
}

JavaScript:

function filesSelected(){
  //...
  try {
    await doc.loadSource(blob);
  } catch (error) {
    if (error.cause.code === -80202) {
      askForPassword();
    }
  }
}

function askForPassword(){
  document.getElementById("password").value = ""; //clear previous password
  document.getElementsByClassName("input-modal")[0].classList.add("active");
}

document.getElementById("okayBtn").addEventListener("click",async function(){
  document.getElementsByClassName("input-modal")[0].classList.remove("active");
  try {
    await doc.loadSource({fileData:blob,password:document.getElementById("password").value});  
  } catch (error) {
    alert(error);
  }
})

We have to pass the password info to the loadSource method:

await doc.loadSource({fileData:blob,password:document.getElementById("password").value});  

Save a Password-Protected PDF

We can save the PDF without password to create a decrypted PDF or set a password to create an encrypted PDF.

<div>
  <label>Set a password:
    <input type="password" id="newPassword"/>
  </label>
</div>
<script>
let newPassword = document.getElementById("newPassword").value;
let blob;
if (newPassword) {
  blob = await doc.saveToPdf({password:newPassword});
}else{
  blob = await doc.saveToPdf();
}
</script>

Source Code

Get the source code of the demo to have a try:

https://github.com/tony-xlh/PDF-Encryption-JavaScript