I have an application where a user buys "gift card pins". Once they have completed their purchase, we, as a broker, buy the pins from a 3rd party and need to deliver them to the end user.

Once we have the pins, we need to upload them for the user to be able to use like a normal card. Due to needing this being sensitive data but at the same time, data that needs to be eventually shown to the end user, I am stuck on a best approach here.

I need to store these codes securely but at the same time, be able to decode them as the end user needs to see the code to user on merchant XYZ's website.

The application uses PHP's CodeIgniter framework which has a built in encryption library.



The pin is then encrypted and stored in the MySQL DB and can be retrieved with:


The issue with this, from a security standpoint is that the PHP application has the encryption key stored within it so that it can run these methods.

I don't think I can use hashing in this situation as I need to eventually know the true value of the data.

Any suggestions on an approach for this?

  • I'm not sure it's clear what you mean by "The issue with this is that the PHP application has access to the encryption key." What is the issue, specifically? From your description above, it sounds like the PHP applications needs to have access to the decrypted data. Jan 8, 2018 at 19:57
  • @user52472 - I guess issue isn't the right word to use but I just don't know if its the best (may be the only) way to handle it. If some one was able to exploit the application and that key is just sitting there, I might as well have the pins stored in plain text in the database. Just not sure how else to go about it.
    – SBB
    Jan 8, 2018 at 19:59
  • This becomes a question of the threat you are trying to protect against. Encrypting database values/data at rest protects you against the datastore itself being compromised. It can't protect against an attack on the endpoint (in this case, the web application) Jan 8, 2018 at 20:04
  • The purpose of your application is to store a secret and reveal it to an authorized user at the right time. This doesn't work without having access to said secret. I am afraid there isn't much to say here except for the obvious: "Don't have any security holes in your application".
    – Philipp
    Jan 8, 2018 at 20:05
  • @Philipp - Thanks, I just needed some reassurance that there wasn't really anything better I could be doing for this situation. If the user never needed to be able to access the code at a later time, I wouldn't even store it at all and just deliver it right to them. Sadly, requirements say otherwise. Thanks for the information.
    – SBB
    Jan 8, 2018 at 20:07

2 Answers 2


The purpose of your application is to store a secret and reveal it to an authorized user at the right time. This doesn't work without being able to decrypt said secret. I am afraid that any solution where your organization is completely unable to access the secret is not going to work. So the only security practice which is going to protect you from the worst case scenario is the obvious one: "Don't have any security holes in your application."

However, encrypting data at rest in the database can still make sense if you want to compartmentalize knowledge of different departments in your company.

For example, if only the application server admin has access to the decryption keys used in the production environment, then you can grant any database admins and developers read-access to the production database without having to worry about them stealing any pins. The majority of day-to-day issues will be solvable without requiring the pins in clear-text. Just keep in mind that there will still be situations where in order to troubleshoot a problem someone must decrypt a pin in the production database. So make sure that your processes allow an exception for these situations.

This, of course, only applies if your organization is actually big enough for such a compartmentalization to make sense. When you are a small business where DBA, server admin, developer and security manager are the same person, all of this is pointless.

It might also help in those situations where unauthorized people gain read-access to your database (for example through an SQL injection or database server misconfiguration) but not to the server configuration where the decryption key is stored. But remember that this is just a limited subset of possible attack scenarios.

But in any case, be careful not to overengineer on your at-rest data encryption. The fancier your solution, the more bugs it will have. And the more bugs it has, the more situations you will have where people are forced to look at the decrypted data in order to fix said bugs.

  • Thanks for the information - I will certainly keep the data encrypted in the DB and secure the app as best as possible.
    – SBB
    Jan 8, 2018 at 20:28

You may want to look into solutions to handle the encryption and decryption process out of the main application logic.

You may want to try to incorporating an HSM or (SaaS HSM, like AWS CloudHSM) to do encryption and decryption processes for you, this would reduce any hardcoded security variables in your code and make tampering even by people with your organization difficult.

Depending on your needs, you may also want to try to a secrets manager, like hashicorp-vault, or privileged identity management tool, like thycotic secret server. These tools can do things like password rotation, audit trails, etc.

From your OP, I am not 100% sure of your logic, but it sounds like maybe you want to assign the code to the user at purchase time. If this is the case, you can reduce exposure by instead assigning the user a reservation for a code and then pulling it only when they request and make it "one time only" -e.g., they need to write it down or they can never get it again or at the very least you only make it exposed to the user after they actually first say they need to redeem it.

Again, here the use of an HSM may be helpful to keep the list of pin codes secure until they are assigned or actually used to manage the assignment.

Ideally, every user would have a private-public keypair and you could just encrypt the value so that only the specific user could decrypt. However, this is pretty hard to do in a web app.

Think of a similar setup to something like LastPass that stores people's passwords, but LastPass doesn't just have a big plaintext database of people's stored passwords.

You may also be interested in taking a look at MIT Mylar and how it deals with sensitive data management and protection.

Check out:

Also consider that you need to think about when you get the list of cards and pins from your supplier. You will need to have this file protected and then you may have intermediary files sitting around from this process. i.e., Look at where the data may be exposed on its way to the app/db as there could be other places for it to be exposed.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .