I am building a PHP web application, that needs enhanced security, due to the fact that it contains very sensitive information (in a database).

I think that I want to use self-signed SSL certificates that will correspond to each user and store them one level above the web root folder (for simplicity's sake /var/www/certs where the root is /var/www/domain1.com). I would disagree on the option to store the key and IV in the database due to the fact that if an attacker obtains a copy of the database he has the keys for all doors, which makes the encryption useless IMO. That is the reason why I am considering using the p12 certificates, only as a key and vector storage.

Are there any chances that an attacker who gains access to the application, by exploit or any other method, would be able to get access to the certs if they did not previously know about them? (The scenario is if an attacker exploits vulnerability in the application itself, not in the server, to get access to a files that he is not aware of)

  • Could you please clarify whether you're concerned with one user accessing data from other users, or just with an external attacker accessing data from any of your users? Also, I'm assuming the server itself is trusted, i.e. it can access data from every user. Otherwise, things would get a bit tricky...
    – mgibsonbr
    Commented Jul 23, 2013 at 3:25
  • what do you mean with "self-signed SSL certificates that will correspond to each user"; do you want to authenticate your users via client-based certs or do you mean ssl-encryption-certs? Commented Jul 23, 2013 at 6:34
  • as I mentioned in the comment to @AJ's answer the certificates will be created as an storage file, was thinking to use the certificates(certificates like those which are used in authentication for example *.pk12) and to use a part of their Footprints for encryption key and IV in CFB encryption. Commented Jul 23, 2013 at 11:01
  • @mgibsonbr yes the data is stored on a trusted server(the server the application is hosted) and the concerns are if an attacker could get access to the user data, and with lower priority is a user accesing other users data Commented Jul 23, 2013 at 11:20

3 Answers 3


If an attacker has access only to the "live" database (most commonly via SQL injection), then encrypting the fields using some secret not stored in the database is enough - even some hard-coded secret key in the application code or configuration file. There's no need to use per-client keys.

If you're worried an attacker could somehow access the data at your web root, but not the rest of the filesystem (common if your server is misconfigured to allow browsing its web root contents), nothing changes - afterall, your server code or configuration file should be outside the web root, right? (I have little experience with PHP, so I might be wrong about this)

If your concern is an attacker getting hold of the whole filesystem, then you should ensure the key only exists in RAM. One way of doing that would be requiring a password to be entered at server (re)start, and keeping the derived key in a globally accessed variable (again, I dunno if it's possible with PHP). There might be other options, but any I can think of would introduce other points of failure.[1]

I was thinking of generating the certificates on registration and use part of the footprint of a certificate to encrypt the user's data. so the SHA1 or MD5 footprint could do as key and IV.

Using anything from the certificate is a bad idea, since certificates are by definition public (the private parts never leave the user machine). If you could somehow have the user decrypt some data using his private key (something that AFAIK is not widely supported right now, but could be in the future), client-side, then you might be up to something... But the way things are now, you could simply create a random key for each user and have your application code read it (from a secure place) and apply it to the user data before inputting/outputting it.

This, of course, assumes you need to isolate one user's data from the other users. If that's not the case, a single global key might suffice, as described in the first part of this answer.

(one last note: you haven't mentioned the method you plan to use to encrypt data. If you're using a stream cipher, for instance, having a single IV for each user is not enough - you need to have a different one for each datum you want to protect. It doesn't matter though how you store them, since they're not supposed to be confidential, just unique. There are ways to make a single IV useable for encrypting a lot of data, but that's beyond my current knowledge, so I won't opinate on them.)

[1]: Just to name one, you could derive an encryption key from the user password, store it in a (secure) session cookie, and pass it back-and-forth from server to client. Since it's not stored anywhere, an attacker won't gain access to it even if he got hold of the whole server (assuming of course your site properly salts and hashes passwords and the authentication key and encryption key are independent of each other). For some defense-in-depth, you could even combine that key with one stored only in the server. The obvious downside is that part of your system security now depends on the user browser, and also the way session cookies are handled both in the server and the client.

  • well I was thinking to use key and IV per user, so that the decryption of user information in case where an attacker has the data, not to be able to get all data with one try(meant to say, if he decrypts 1 entry). So my problem is with storing the Key and Vector for enc/dec. AFAIK if the keys are in the database it is useless to do the encryption, (the key is in the lock) a hard-coded key and vector are not an optionz cuz in case of a breach all data is exposed. Commented Jul 23, 2013 at 11:11
  • @DaGhostmanDimitrov Please read more about symmetric encryption, otherwise you're bound to make a mistake. While you can encrypt a lot of data with a single key per user, reusing an IV can literally void the security properties of a given cipher/mode. Don't worry about the confidentiality of your IVs, just make sure that there are different ones for different data and that they are unique (store them in the DB alongside the data). About your other concern, please see the 3rd paragraph of my answer and the update in the bottom, that might shed some light on what you're looking for.
    – mgibsonbr
    Commented Jul 24, 2013 at 2:31
  • @DaGhostmanDimitrov To illustrate why reusing IV is bad, check this funny example. Some modes of operation (such as CTR) will fail catastrophically if two or more data are encrypted with the same IV, others (like CBC) will offer some resistance but still collapse in the end (especially if an attacker has access to many ciphertexts). Source
    – mgibsonbr
    Commented Jul 24, 2013 at 5:16

You seem to have a fundamental misunderstanding about writing secure software and probably shouldn't attempt to roll your own with your current level of understanding. SSL certificates won't do you any good at all for protecting DB access or the contents of the DB. Not only would people almost certainly be able to get to the certs, but it does nothing to protect you.

To protect a DB, you need to filter input to prevent SQL injection, harden the server itself and if necessary to protect the data at rest, use encryption, which only requires keys that can be encrypted with password derived keys and stored in the database itself.

  • Well I think that the problem is the late time I wrote the question(an even l8er now) But my question was not that. I am experienced enough to be able to protect from CSRF, SQLInjection and etc. I was thinking of generating the certificates on registration and use part of the footprint of a certificate to encrypt the user's data. so the SHA1 or MD5 footprint could do as key and IV. and to remove them form the folders of the application. Please if you could make an edit to the question, please do cuz I see that it is awful, but at 4am I am a bit stuck .. Thanks! Commented Jul 23, 2013 at 2:23
  • +1 for the note, it should always be kept in mind that no matter what the encryption used is, the basics should always be applied Commented Jul 23, 2013 at 2:24
  • 1
    @DaGhostmanDimitrov - your method of approaching encryption is still fundamentally broken. You don't use asymmetric crypto for encryption at rest. You use either a derived or client cert protected data key and use that for encryption. You can either use a password that derives a key which is used to encrypt/decrypt the symmetric data key or you can encrypt the symmetric data key with a client cert public key so that it can only be decrypted by the user. You would then have to submit the decryption key as part of a challenge to the user to get the decryption key once the client and server.. Commented Jul 23, 2013 at 3:04
  • are communicating securely via some other trusted means, such as SSL being used to verify the server to the client. Commented Jul 23, 2013 at 3:04

Are there any chances that an attacker who gains access to the application, by exploit or any other method, would be able to get access to the certs if they did not previously know about them?

Yes, it is not only possible, it is likely. Any file that your application has access to, anyone who takes over you application will also have access to. Typically he'll be able to view directory listings, execute programs, and do anything a normal user could do.

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