How to remove a password from a PDF using ColdFusion

This post is more than 2 years old.

ColdFusion makes it relatively trivial to create a PDF and password protect it. But how do you edit a PDF to remove that password? Let me begin this blog entry by saying that I am convinced that the solution I am about to provide is the wrong way to solve the problem. I truly can't believe that the awesome CFPDF tag, which does so much, doesn't provide for this simple functionality. I'll be happy to be proved right when someone posts the one line solution. Until then, here is how I solved it using DDX and the power of magical unicorns.

Let's begin with a simple example of creating a PDF with password protection. This is documented of course, but I just wanted to show a quick reminder of how easy ColdFusion makes it.

<cfdocument format="pdf" name="secret" userpassword="paris" encryption="128-bit"> <img src="" align="left"> This is the PDF that I'll protect. My bank atm is 5318008. </cfdocument>

<cfheader name="Content-Disposition" value="inline; filename=foo.pdf"> <cfcontent type="application/pdf" variable="#toBinary(secret)#">

This code makes a simple one line PDF, adds the password 'paris', and encrypts the document. I then serve it up witha filename of foo. Here is a quick screen shot of how it comes out in Preview (btw Mac users, you definitely want to assign Preview for PDF files and not Acrobat):

Before the password...

After the password...

Alright, so that's how we can create the password protected PDF, but how do we remove the password? Well I began by trying to use various combinations of cfpdf attributes. I tried to set newUserPassword to a blank string, but that returned an error. I tried setting encrypt to None, which is documented, but was told I didn't have permission. (This was after opening the PDF using the password option which worked just fine.) I spent a good hour just playing around and no combination worked for me.

I was about to give up when I looked to DDX. I've blogged on DDX a few times now (my first entry may be found here) and it is truly a very powerful tool. It can be a bit hard to use at times though. You have to be sure you read the docs carefully and make use of isDDX() to verify your XML is valid. Using DDX to solve this problem involves two steps really.

The first thing we need to do is find out how to simply even work with a password protected PDF. Who cares about removing a password - we just want to be sure we can even use a password protected document to do other tasks. I did some searching in the DDX Reference and discovered that you can provide a PasswordAccessProfile element. This element lets you do a few things, one of which is a password for opening the document. Consider:

<!--- Make and save the pdf ---> <cfdocument format="pdf" name="secret" userpassword="paris" encryption="128-bit"> <img src="" align="left"> This is the PDF that I'll protect. My bank atm is 5318008. </cfdocument>

<cfset fileWrite(expandPath('private.pdf'),secret)>

<cfset pdfpath = expandPath('./private.pdf')> <cfset outfile = expandPath('./notprivate.pdf')>

<cfsavecontent variable="myddx"> <?xml version="1.0" encoding="UTF-8"?> <DDX xmlns="" xmlns:xsi="" xsi:schemaLocation=" coldfusion_ddx.xsd"> <PDF result="Out1"> <PDF source="In1" access="mainP"/> </PDF> <PasswordAccessProfile name="mainP"> <Password>paris</Password> </PasswordAccessProfile> </DDX> </cfsavecontent> <cfset myddx = trim(myddx)>

<cfset inputStruct = {In1="#pdfpath#"}> <cfset outputStruct = {Out1="#outfile#"}>

<cfpdf action="processddx" ddxfile="#myddx#" inputfiles="#inputStruct#" outputfiles="#outputStruct#" name="ddxVar"> <cfdump var="#ddxVar#">

This script recreates the PDF from the previous version and saves it to the file system. DDX requires all actions to be performed at the file system and can't work with PDFs in ColdFusion variables. The DDX I created makes use of PasswordAccessProfile. It has a name for the profile, mainP, and a Password element with the password I supplied when creating the PDF. Notice than that my PDF source uses access="mainP" to say, "When accessing this PDF, use this profile." That's it really - I don't actually perform any actions on the PDF, I just open it and return it. It's the BAT file equivalent of reading a file and saving it to a new file name.

The next step is to remove the password. That turns out to be rather simple as well. All we need to do is modify the PDF result tag and supply an encryption value:

<?xml version="1.0" encoding="UTF-8"?> <DDX xmlns="" xmlns:xsi="" xsi:schemaLocation=" coldfusion_ddx.xsd"> <PDF result="Out1" encryption="None"> <PDF source="In1" access="mainP"/> </PDF> <PasswordAccessProfile name="mainP"> <Password>paris</Password> </PasswordAccessProfile> </DDX>

I've supplied the None value which basically just strips out the encryption. Note - remember how I said DDX was a bit anal? If you use "none", as I did at first, it will not work. But it will actually pass the isDDX test, so you have to be careful.

So that's it. If I'm wrong and this is the only way to remove passwords from PDF, I'll make this a bit cleaner and add it to my pdfUtils utility CFC.

Comments? I've included the test code to this blog entry.

Download attached file.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA

Archived Comments

Comment 1 by Jochem van Dieten posted on 1/23/2009 at 9:57 PM

PDFs have 2 passwords, a user password and an owner password. If you use the owner password instead of the user password in combination with "none" encryption it will work just fine:
<cfpdf action="protect" source="protected.pdf"
newUserPassword = "test"
newOwnerPassword = "test"
permissions = "All"
destination = "unprotected.pdf"
encrypt = "none"
overwrite = "yes"
password = "user" />

Comment 2 by Raymond Camden posted on 1/23/2009 at 10:00 PM

Thanks Jochem! I still say CFPDF needs to be 'fixed' to handle a PDF with just a userpassword and not an ownerpassword. I'm still going to add this to pdfUtils, but I'll be sure to document the fact that if you _are_ creating the PDF then you can use the ownerpassword as a way around it.

Comment 3 by JC posted on 1/23/2009 at 10:01 PM

Given that it would have been trivial for Adobe to add a function to strip passwords from PDFs, I'd suspect that they simply didn't think the idea of effectively building a cracking mechanism for one of their products into another of their products was a good precedent.

Comment 4 by Raymond Camden posted on 1/23/2009 at 10:04 PM

Um, this is not even close to cracking. I -made- the PDF. I -knew- the password. What if I wanted to provide a dynamic sample of the PDF? I'd need to remove the password and delete pages 5-*, or whatever. That is a perfectly legitimate use case for removing a password from a pdf!

Comment 5 by Andrew Scott posted on 1/24/2009 at 5:40 PM

@Ray, I am not sure that the ColdFusion tag should be fixed, But more that the DDX should be more aware of the password. As mentioned Owner Password stops people from doing this sort of thing, and the ability to stop the PDF from being edited is another option.

If DDX is ignoring those two options then the problem is in DDX and not ColdFusion, in my eyes.

Comment 6 by Raymond Camden posted on 1/24/2009 at 7:43 PM

I don't know. Maybe. Jochem shared (on another list) the PDF spec docs, and in my reading there I didn't see a clear 'you must use both' directive.

Who knew we would spend so much time on such a small detail in PDF files? ;)

Comment 7 by Peter Tilbrook posted on 3/27/2013 at 5:09 AM

What if you dont' the original password?

Comment 8 by Raymond Camden posted on 3/27/2013 at 5:11 AM

Don't "know" I assume? Then you are screwed unless you hack it.

Comment 9 by kanima posted on 7/6/2015 at 8:46 AM

it's nice pdf remover
thanks for shared