Restrict users from uploading signed PDFs

We have a customer portal where we allow our customers to upload several documents(PDF only) as required. These documents after getting uploaded to SFDC are then also sent to our other systems.

While this is working fine, we are observing some issues when users tries to upload signed PDFs, to be specific, PDFs signed using itext. The PDFs get uploaded successfully in SFDC, however while sending them from SFDC to our other systems, they fail.

I wanted to know if there is a way by which I can restrict our customers from uploading PDFs that are signed. OR even simply restricting them from uploading PDFs signed using itext.

NOTE: I understand this may not be the correct way to go with this problem, but until our other systems allow signed PDFs, I will have to restrict users from uploading them.



PDF files are binary files, and as such, we can’t just load it up into a string directly and examine the data to determine if a signature marker is present; it would probably require too much processing time on all but simple PDFs anyways (those less than about 1mb). However, we can check against a simple heuristic that will tell us, with fair likelihood, if a file is signed or not.

A signed PDF will contain one of the following textual signatures within the code:


Since we can’t work with binary data, we’re forced to work in Base64 text to try and decipher the code. This means that the code will be in one of three possible Base64 positions. Based on that information, we could look for the base64 encoded values of:


Each signature is necessary because base64 bytes are not aligned with real bytes, so there are three possible combinations for strings we have to find. This is because the bytes we can detect must be byte aligned:

[Pre] [Detection  Range] [Post]
  123 123123123123123123 123
      /adbe.pkcs7.detach ed
    / adbe.pkcs7.detache d
   /a dbe.pkcs7.detached

Here are the relevant base64 signatures we can scan (from above) in base64:


We can’t determine the bits before or after accurately, because they are not byte (and therefore character) aligned. We could, of course, check the bounding characters (4 on either side) and decode them to make sure that the appropriate strings (any in the first list) appear completely, but this is probably not necessary, since those strings are fairly uncommon in normal text (unless, of course, you’re talking about a paper on signed PDFs!).

So, a probably sufficient detection algorithm would go along the lines of this:

Set<String> signatures = new Set<String> {
String blobAsString = EncodingUtil.base64Encode(theAttachment.Body);
Boolean isSigned = false;
for(String signature: signatures) {
    isSigned = blobAsString.indexOf(signature) != -1;
    if(isSigned) {
if(isSigned) {
    // stop upload from happening

I tested this against two PDF files in my developer org. The first was a PDF that was an old paycheck PDF from my employer, the other the test signature file from the original post comments.

In my test code, the results are as follows:

"Unsigned Test PDF":  USER_DEBUG [20]|ERROR|false
"Signed Test PDF": USER_DEBUG [20]|ERROR|true

In other words, detection was successful with 100% accuracy, but this is only a small sample of data. I would consider putting a logging mode in for a month or so, log the results of this scan, and see how many false positives/negatives that you get. You may need to fine-tune the algorithm if you find many false results.

You could probably also simply scan for the following signatures:


Then scan backwards until you find the /SubFilter marker, and make sure the format is what is expected, then scan forward to make sure it actually matches one of the target strings that identifies a signature. That logic would be even more accurate, but slower; I chose to go with a simple algorithm that should pass with over 99% confidence in normal texts.

I found the target strings from the document that explains signing: iTextPDF signatures.

Source : Link , Question Author : Shailesh Deshpande , Answer Author : sfdcfox

Leave a Comment