By Thom Parker October 19, 2007
Scope: Acrobat 7.0 and later
Skill Level: Intermediate and Advanced
Prerequisites: Basic Acrobat JavaScript Programming
If you routinely apply the same security to PDF files, then it is worthwhile to automate the process. This article will show you how to use Acrobat JavaScript to create a toolbar button that applies security on demand to a single PDF with one click. Keep in mind that security is a large and complex topic. There are many different kinds of security and many different ways to apply it to a PDF. For instance, if you need to handle large folders full of documents, it’s best to use a batch sequence with the “Security” command. This batch command allows you to apply password, certificate or even Policy Server security to a PDF and is easy to use.
Acrobat JavaScript contains several objects, functions and properties for handling different aspects of PDF security. For example, the doc.securityHandler property provides the name of the document’s current security handler, if any. Try it out by applying security to a PDF and then running this code in the Acrobat JavaScript Console:
doc.securityHandler
A security handler is an Acrobat plug-in responsible for encrypting and decrypting the PDF. Third-party vendors can create their own security handlers, and many have, but Acrobat provides several default security handlers. You can see which ones are available on your system by running the following code in the JavaScript Console:
security.handlers
This property contains an array of the names of all currently available security handlers. If the particular handler needed by the PDF is not available, Acrobat will not be able to open the PDF.
Acrobat JavaScript has two Document Object functions for applying security, doc.encryptForRecipients() and doc.encryptUsingPolicy(). The doc.encryptForRecipients() function uses a list of digital certificates to encrypt a PDF, so only those people that have those certificates can view the PDF. This is a great way to handle document security in a closed system. But using this function is fairly complex, and what we want is a simple way to quickly apply security. The doc.encryptUsingPolicy() function provides us with just such an option.
Security policies were added as a feature in Acrobat 7. A security policy is a set of parameters that describe how security should be applied to a document. Users can create as many policies as they want. Each one has a name, and Acrobat keeps track of them. A policy can then be applied to any PDF by simply specifying the policy’s name. The actual parameters in the policy could be anything; password security, digital certificate security, advanced policy server security and so on. By putting all the security information into a policy, users (and/or JavaScript) can apply security to documents without having to deal with the underlying details. This allows office managers or IT professionals to set up everyone in an office with the ability to apply PDF security, without having to train anyone on anything more complex than pushing a toolbar button or selecting a menu item.
Automation scripts are typically run from an Acrobat menu item or toolbar button. I prefer toolbar buttons. They are very easy for novice users to deal with and a good icon makes it instantly recognizable. Toolbar buttons are added to Acrobat with the following code:
app.addToolButton({cName: "MySecurityButton", cLabel: "Add Security", cEnable: "event.rc = (app.doc != null);", cExec: "DoApplyMySecurity();" });
The “cName” argument is the name of the button. It is used to identify the button by other functions, such as app.removeToolButton(). The “cLabel” argument is the text that appears on the face of the toolbar button. The “cEnable” argument is a snippet of code that determines whether the button is enabled for use, or grayed out. There are other input arguments, most notably “oIcon,” which provides a small picture to be displayed on the button. If there is a label, then the icon is optional. But the main argument of interest is “cExec,” which holds the script that will be run when the button is pushed. In our case, it’s a call to the DoApplyMySecurity() function. This is the function we’ll create to apply security. The code for this function is shown below:
var DoApplyMySecurity = app.trustedFunction( function(){ var oMyPolicy = null; app.beginPriv(); // First, Get the ID of My Security Policy var aPols = security.getSecurityPolicies() for(var index=0;index<aPols.length;index++){ if(aPols[index].name == "MySecurityPol"){ oMyPolicy = aPols[index]; break; } } if(oMyPolicy == null){ app.alert("Policy Not Found"); return; } // Now, Apply the security Policy var rtn = this.encryptUsingPolicy({oPolicy: oMyPolicy }); if(rtn.errorCode != 0) app.alert("Security Error: " + rtn.errorText); app.endPriv(); });
This function does everything we need and, despite how it looks, it’s actually quite simple. But, before we get into the details of how security is applied, it’s important to discuss the form of the function.
On the first line of the code, you can see that the app.trustedFunction() is used to create our function. This is critical. In JavaScript, security can only be applied to a PDF from a privileged context. Unfortunately, a toolbar button script is not privileged, so we use app.trustedFunction() to create privilege. Our function can be called from anywhere and it will work because app.trustedFunction() grants our function the coveted privilege.
So what’s a privileged context? It’s simply a code location that is trusted by the system to perform risky operations like applying security. The JavaScript Console Window is a privileged context because the user has to personally type in the code, and we trust users on their own systems. By far the most common privileged context is a folder-level script, which is where we’ll be placing the code in this example. We can’t just create a trusted function out of nowhere; app.trustedFunction() can only be called from another privileged context and a folder-level script is perfect. These scripts are run on Acrobat startup, so the toolbar button and privileged function will be set up whenever Acrobat is run.
Now, let’s get into the details of the script itself. The DoApplyMySecurity() function has two parts. In the first part, a “for” loop is used to walk through all the security policies until if finds “MySecurityPol”, which is the name I gave the security policy when I created it. If a policy with that name is not found, an alert box is displayed.
The policy is applied in the second part of the script with doc.encryptUsingPolicy(). This function has several input parameters that allow the script developer to use it in a variety of ways. But we’re only interested in the simplest configuration, which uses the policy object as the only input. This works very well for the basic password and certificate security handlers. Security for these handlers is applied silently as long as the policy contains everything it needs. Other types of security can require user input for authentication or more complex interactions. doc.encryptUsingPolicy() has inputs for handling some of these situations. But security can be complex, and if you are using something non-standard, you will need to experiment with the security policy parameters and the JavaScript functions to get things working correctly.
The sample for this article is a folder-level JavaScript file, “JSApplySecurity.js.” It’s contained in this zip file, “JSApplySecurity.zip.” In order to use the sample, you’ll need to unzip this file into Acrobat’s JavaScript Folder, which you can find by reading this article, “Folder Level Scripting.” You will also need to create a Security Policy named “MySecurityPol” from the “Advanced > Security > Manage Security Policies…” menu item. It doesn’t matter what’s in this policy, just that it’s there. The only difference between the code in the text of this article and the code in the example file is that an icon is provided for the toolbar button in the example. The icon is a large block of hexadecimal text. Ignore it while you are looking at the code.
To summarize, the script only needs to take two actions to apply the security policy to a document. First, it has to find the object for our security policy by searching entries in array of security policies returned from the security.getSecurityPolicies() function. Second, it applies security to the current document by passing the security policy object into the doc.encryptUsingPolicy() function. Since both of these functions require privilege, our script is packed into a function and enabled for privileged operation with app.trustedFunction().
For more information on these and related functions see both The Acrobat JavaScript Reference and The Acrobat JavaScript Guide.
https://www.adobe.com/devnet/acrobat.html
Click on the Documentation tab and scroll down to the JavaScript section.