Monday, 7 March 2016

PDFBox: Encrypt, password protect PDF Document

In this post, I am going to explain you how to encrypt a pdf document using Apache PDFBox.


Following snippet is used to encrypt and protect the document using password.
public static boolean encryptDocument(final String fileName,
   final String encryptedFileName, final int keyLength,
   final String ownerPassword, final String userPassword) {
 try (PDDocument doc = PDDocument.load(new File(fileName))) {
  AccessPermission ap = new AccessPermission();

  /* disable printing, everything else is allowed */
  ap.setCanPrint(false);

  StandardProtectionPolicy spp = new StandardProtectionPolicy(ownerPassword, userPassword, ap);

  /*
  * Define the length of the encryption key. Possible values are 40,
  * 128 256
  */
  spp.setEncryptionKeyLength(keyLength);
  spp.setPermissions(ap);
  doc.protect(spp);

  doc.save(encryptedFileName);
  return true;
 } catch (IOException e) {
  System.out.println(e.getMessage());
  return false;
 }
}


Complete utility class after adding encryption functionality looks like below.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDMetadata;
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
import org.apache.pdfbox.text.PDFTextStripper;

public class PDFTextStripperUtil {

 /**
  * @param fileName
  * @return complete file data as string
  * @throws NullPointerException
  *             if fileName is null
  */
 public static Optional<String> getDataAsString(final String fileName) {
  if (Objects.isNull(fileName)) {
   throw new NullPointerException("fileName shouldn't be null");
  }

  try (final PDDocument pdDoc = PDDocument.load(new File(fileName))) {

   PDFTextStripper stripper = new PDFTextStripper();
   stripper.setLineSeparator("\n");
   stripper.setAddMoreFormatting(true);

   return Optional.of(stripper.getText(pdDoc));

  } catch (IOException e) {
   System.out.println(e.getMessage());
   return Optional.empty();
  }

 }

 public static Optional<String> getDataAsString(final String fileName,
   final int startPage, final int endPage) {
  if (Objects.isNull(fileName)) {
   throw new NullPointerException("fileName shouldn't be null");
  }

  if (startPage < 1 || endPage < 1 || endPage < startPage) {
   throw new IllegalArgumentException(
     "startPage, endPage must >= 1 and  endPage >= startPage");
  }

  try (final PDDocument pdDoc = PDDocument.load(new File(fileName))) {

   PDFTextStripper stripper = new PDFTextStripper();
   stripper.setLineSeparator("\n");
   stripper.setAddMoreFormatting(true);
   stripper.setStartPage(startPage);
   stripper.setEndPage(endPage);

   return Optional.of(stripper.getText(pdDoc));

  } catch (IOException e) {
   System.out.println(e.getMessage());
   return Optional.empty();
  }
 }

 public static Optional<String> getDataAsStringFromStartPage(
   String fileName, int startPage) {
  if (Objects.isNull(fileName)) {
   throw new NullPointerException("fileName shouldn't be null");
  }

  if (startPage < 1) {
   throw new IllegalArgumentException("startPage must >= 1");
  }

  try (final PDDocument pdDoc = PDDocument.load(new File(fileName))) {
   int noOfPages = pdDoc.getNumberOfPages();
   return getDataAsString(fileName, startPage, noOfPages);

  } catch (IOException e) {
   System.out.println(e.getMessage());
   return Optional.empty();
  }
 }

 public static Optional<String> getDataAsStringTillEndPage(String fileName,
   int endPage) {
  if (Objects.isNull(fileName)) {
   throw new NullPointerException("fileName shouldn't be null");
  }

  if (endPage < 1) {
   throw new IllegalArgumentException("endPage must >= 1");
  }

  return getDataAsString(fileName, 1, endPage);
 }

 public static Optional<Integer> getNumberOfPages(String fileName) {
  if (Objects.isNull(fileName)) {
   throw new NullPointerException("fileName shouldn't be null");
  }
  try (final PDDocument pdDoc = PDDocument.load(new File(fileName))) {
   return Optional.of(pdDoc.getNumberOfPages());
  } catch (IOException e) {
   System.out.println(e.getMessage());
   return Optional.empty();
  }
 }

 public static Optional<Map<String, Object>> getDocumentBasicMetaData(
   final String fileName) {
  if (Objects.isNull(fileName)) {
   throw new NullPointerException("fileName shouldn't be null");
  }

  try (final PDDocument pdDoc = PDDocument.load(new File(fileName))) {
   PDDocumentInformation docInfo = pdDoc.getDocumentInformation();
   Set<String> keys = docInfo.getMetadataKeys();

   Map<String, Object> map = new HashMap<>();

   for (String key : keys) {
    map.put(key, docInfo.getPropertyStringValue(key));
   }

   return Optional.of(map);

  } catch (IOException e) {
   System.out.println(e.getMessage());
   return Optional.empty();
  }
 }

 public static Optional<List<String>> getCatalogMetaData(
   final String fileName) {
  if (Objects.isNull(fileName)) {
   throw new NullPointerException("fileName shouldn't be null");
  }

  try (final PDDocument pdDoc = PDDocument.load(new File(fileName))) {
   PDDocumentCatalog catalog = pdDoc.getDocumentCatalog();
   PDMetadata metadata = catalog.getMetadata();
   return getMeatData(metadata);
  } catch (IOException e) {
   System.out.println(e.getMessage());
   return Optional.empty();
  }

 }

 private static Optional<List<String>> getDataFromStream(InputStream in) {

  try (BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
   List<String> data = new ArrayList<>();
   String str;

   while ((str = br.readLine()) != null) {
    data.add(str);
   }
   return Optional.of(data);
  } catch (IOException e) {
   System.out.println(e.getMessage());
   return Optional.empty();
  }

 }

 private static Optional<List<String>> getMeatData(PDMetadata metadata) {
  if (metadata == null) {
   System.out.println("There is no meta data associated");
   return Optional.empty();
  }

  try (InputStream in = metadata.createInputStream()) {
   return getDataFromStream(in);
  } catch (IOException e) {
   return Optional.empty();
  }
 }

 public static Optional<List<String>> getPDPageMetaData(
   final String fileName, int pageIndex) {
  if (Objects.isNull(fileName)) {
   throw new NullPointerException("fileName shouldn't be null");
  }

  if (pageIndex < 1) {
   throw new IllegalArgumentException("pageIndex must >= 1");
  }

  try (final PDDocument pdDoc = PDDocument.load(new File(fileName))) {

   if (pageIndex > pdDoc.getNumberOfPages()) {
    throw new IllegalArgumentException("pageIndex : " + pageIndex
      + " must <= " + pdDoc.getNumberOfPages());
   }

   PDPage pdPage = pdDoc.getPage(pageIndex);
   PDMetadata metadata = pdPage.getMetadata();
   return getMeatData(metadata);
  } catch (IOException e) {
   System.out.println(e.getMessage());
   return Optional.empty();
  }
 }

 public static boolean encryptDocument(final String fileName,
   final String encryptedFileName, final int keyLength,
   final String ownerPassword, final String userPassword) {

  if (Objects.isNull(fileName)) {
   throw new NullPointerException("fileName shouldn't be null");
  }

  if (Objects.isNull(encryptedFileName)) {
   throw new NullPointerException(
     "encryptedFileName shouldn't be null");
  }

  if (keyLength < 1) {
   throw new IllegalArgumentException("keyLength should > 0");
  }

  if (Objects.isNull(ownerPassword)) {
   throw new NullPointerException("ownerPassword shouldn't be null");
  }

  if (Objects.isNull(userPassword)) {
   throw new NullPointerException("userPassword shouldn't be null");
  }

  try (PDDocument doc = PDDocument.load(new File(fileName))) {
   AccessPermission ap = new AccessPermission();

   /* disable printing, everything else is allowed */
   ap.setCanPrint(false);

   StandardProtectionPolicy spp = new StandardProtectionPolicy(
     ownerPassword, userPassword, ap);

   /*
    * Define the length of the encryption key. Possible values are 40,
    * 128 256
    */
   spp.setEncryptionKeyLength(keyLength);
   spp.setPermissions(ap);
   doc.protect(spp);

   doc.save(encryptedFileName);
   return true;
  } catch (IOException e) {
   System.out.println(e.getMessage());
   return false;
  }
 }

 public static boolean encryptDocument(final String fileName,
   final String encryptedFileName, final String ownerPassword,
   final String userPassword) {
  return encryptDocument(fileName, encryptedFileName, 128, ownerPassword,
    userPassword);
 }

 public static boolean encryptDocument(final String fileName,
   final String ownerPassword, final String userPassword) {
  if (Objects.isNull(fileName)) {
   throw new NullPointerException("fileName shouldn't be null");
  }

  File file = new File(fileName);
  String encryptedFileName = "encrypted_" + file.getName();
  return encryptDocument(fileName, encryptedFileName, 128, ownerPassword,
    userPassword);
 }

}

import java.io.IOException;

public class PDFTextStripperUtilTest {
 public static void main(String args[]) throws IOException {
  String fileName = "/Users/harikrishna_gurram/Downloads/Saurabh.pdf";
  String encryptedFileName = "/Users/harikrishna_gurram/Downloads/Saurabh_encrypted.pdf";

  boolean status = PDFTextStripperUtil.encryptDocument(fileName,
    encryptedFileName, "owner123", "user123");

  if (status == true) {
   System.out.println("File is encrypted");
  } else {
   System.out.println("File encryption failed");
  }
 }

}




Previous                                                 Next                                                 Home

No comments:

Post a Comment