How to Encrypt PDF files using Foxit PDF SDK (Java)
Foxit PDF SDK provides a range of encryption and decryption functions to meet different levels of document security protection. Users can use regular password encryption and certificate-driven encryption, or use their own security handler for custom security implementation. It also provides APIs to integrate with the third-party security mechanism (Microsoft RMS). These APIs allow developers to work with the Microsoft RMS SDK to both encrypt (protect) and decrypt (unprotect) PDF documents.
Note: For more detailed information about the RMS encryption and decryption, please refer to the simple demo “security” in the “examples\simple_demo” folder of the download package.
Example:
How to encrypt a PDF file with a Certificate
import com.foxit.sdk.pdf.CertificateEncryptData; import com.foxit.sdk.pdf.CertificateSecurityCallback; import com.foxit.sdk.pdf.CertificateSecurityHandler; import java.io.File; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.util.ArrayList; import java.util.Random; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.util.Enumeration; import java.security.Key; import java.security.KeyStore; import java.security.cert.CertificateFactory; import javax.crypto.Cipher; ... // Assuming PDFDoc doc has been loaded. ... public static Key getPublicKey(String cerPath) { try { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); FileInputStream stream = new FileInputStream(cerPath); java.security.cert.Certificate certificate = certificateFactory.generateCertificate(stream); stream.close(); return certificate.getPublicKey(); } catch (Exception e) { e.printStackTrace(); } return null; } private static byte[] cryptByKey(byte[] inputData, Key key, int opmode) { if (inputData == null) return null; // The max length of decrypted byte array: 128 final int max_crypt_block = 128; try { Cipher cipher = Cipher.getInstance(key.getAlgorithm()); cipher.init(opmode, key); int len = inputData.length; ByteArrayOutputStream stream = new ByteArrayOutputStream(); int offSet = 0; byte[] data; // Decrypt data segment by segment while (len > offSet) { data = cipher.doFinal(inputData, offSet, (len - offSet > max_crypt_block) ? max_crypt_block : (len - offSet)); stream.write(data, 0, data.length); offSet += max_crypt_block; } byte[] outputData = stream.toByteArray(); stream.close(); return outputData; } catch (Exception e) { e.printStackTrace(); } return null; } public static byte[] encryptByKey(byte[] plainData, Key key) { return cryptByKey(plainData, key, Cipher.ENCRYPT_MODE); } public class CertificateSecurityEvent extends CertificateSecurityCallback { private String filePath; private String password; public CertificateSecurityEvent(String filePath, String password) { this.filePath = filePath; this.password = password; } @Override public void release() {} @Override public byte[] getDecryptionKey(byte[] arg0) { return CryptUtil.decryptByKey(arg0, CryptUtil.getPrivateKey(filePath, password)); } } Random rand = new Random(23); byte[] seed = new byte[24]; rand.nextBytes(seed); for (int i = 20; i < 24; i++) { seed[i] = (byte) 0xFF; } PDFDoc doc = new PDFDoc(input_file); int error_code = doc.load(null); if (error_code != e_ErrSuccess) { System.out.println("The Doc " + input_file + " Error: " + error_code); return; } // Do encryption. String cert_file_path = input_path + "foxit.cer"; ArrayList< byte[]> envelopes = new ArrayList< byte[]>(); byte[] bytes=null; try { bytes = CryptUtil.encryptByKey(seed, CryptUtil.getPublicKey(cert_file_path)); envelopes.add(bytes); } catch (Exception e) { System.out.println("[Failed] Cannot get certificate information from " + cert_file_path); return; } byte[] data=new byte[20+bytes.length]; System.arraycopy(seed, 0, data, 0, 20); System.arraycopy(bytes, 0, data, 20, bytes.length); MessageDigest messageDigest = MessageDigest.getInstance("SHA1"); messageDigest.update(data); byte[] initial_key = new byte[16]; System.arraycopy(messageDigest.digest(),0,initial_key,0,16); CertificateSecurityHandler handler = new CertificateSecurityHandler(); CertificateEncryptData encrypt_data = new CertificateEncryptData(true, SecurityHandler.e_CipherAES, envelopes); handler.initialize(encrypt_data, initial_key); doc.setSecurityHandler(handler); String output_file = output_directory + "certificate_encrypt.pdf"; doc.saveAs(output_file, PDFDoc.e_SaveFlagNoOriginal); ...
How to encrypt a PDF file with Foxit DRM
import com.foxit.sdk.pdf.DRMSecurityCallback; import com.foxit.sdk.pdf.PDFDoc; import com.foxit.sdk.pdf.SecurityHandler; ... public class DRMSecurityEvent extends DRMSecurityCallback { private String fileID; private byte[] initialKey; public DRMSecurityEvent(String fileID, byte[] initialKey) { this.fileID = fileID; this.initialKey = initialKey; } @Override public void release() {} @Override public int getCipherType(PDFDoc arg0, String arg1) { return SecurityHandler.e_CipherAES; } @Override public String getFileID(PDFDoc arg0, String arg1) { return fileID; } @Override public byte[] getInitialKey(PDFDoc arg0, String arg1) { return initialKey; } @Override public int getKeyLength(PDFDoc arg0, String arg1) { return 16; } @Override public int getUserPermissions(PDFDoc arg0, String arg1) { return 0xFFFFFFFC; } @Override public boolean isOwner(PDFDoc arg0, String arg1) { return true; } } PDFDoc doc = new PDFDoc(input_file); int error_code = doc.load(null); if (error_code != e_ErrSuccess) { return; } // Do encryption. DRMSecurityHandler handler = new DRMSecurityHandler(); String file_id = "Simple-DRM-file-ID"; String initialize_key = "Simple-DRM-initialize-key"; DRMEncryptData encrypt_data = new DRMEncryptData(true, "Simple-DRM-filter", SecurityHandler.e_CipherAES, 16, true, 0xfffffffc); handler.initialize(encrypt_data, file_id, initialize_key); doc.setSecurityHandler(handler); String output_file = output_directory + "foxit_drm_encrypt.pdf"; doc.saveAs(output_file, PDFDoc.e_SaveFlagNoOriginal); ...
Updated on May 8, 2019