Search code examples
codeignitertcpdfphpass

Using TCPDF and PHPass causing headaches with generating PDFs.


I've got a Codeigniter app that is an extension of an old phone directory my company used to send to employees. So for people who want a print out they had me create a method for "printing" that was a bit more robust than simple HTML to paper. The app has the user download a PDF. However, they also didn't want the PDF easily readable so they had me password protect the PDF with the user's password. This all worked fine in the world of terrible security (storing the raw password in the database)...

Now though I've implemented PHPass to hash all the passwords and this breaks the PDF generation portion. When using $this->pdf->SetProtection in Codeigniter the only thing I can pass in is the hash. This of course does not match what the user is trying to type in after the PDF is downloaded.

Has anyone had any success with modifying how a PDF processes passwords before checking with what's provided in the PDF? So far the only solution I've come up with is to ask them to enter their password again before download but I'd really like to avoid this extra step. Please let me know if you need more to go on. Thanks!


Solution

  • What you are trying to do is impossible. The purpose of hashing is to prevent exactly what you are doing. Hashes are a one-way algorithm meaning that once the password has been hashed by PHPass you can't obtain the original password without a dictionary attack or a hash table.

    There are a few alternatives however to allow you to implement this, all with varying levels of security.

    New Password

    The most secure is as you said to have the user enter a new password when they download the PDF which is passed to TCPDF.

    Cache the Password

    Another alternative which is slightly less secure is to cache the user's plain-text password in the Codeigniter or PHP session on login. You can then use the password stored in the session later on when you need to add a password to the PDF. Personally I would use the PHP session and not Codeigniter because Codeigniter stores its session userdata in a plain-text json array in the sessions table of the database while PHP does not.

    function loginHasCompleted() { $_SESSION['password'] = $_POST['password']; }
    

    Encrypt the Password

    You can also encrypt the password in the database instead of hashing it. By encrypting it with something like AES-256, you can decrypt the password again to use it in the PDF generation. This does pose some security concerns however because if an attacker obtained the AES key used to encrypt the passwords said attacker would be able to decrypt all of the passwords as if they were plain text. It's more secure than plain-text passwords as the attacker would need to obtain both the database and the hard coded key in the source code, but it is still a concern.