0

I'm trying to add a hybrid encryption scheme to my PHP application, and by "hybrid" I mean that each record in the database is encrypted by its own unique symmetric key and each symmetric key is encrypted by a shared private key not stored in the database. The symmetric keys are 256 bit AES keys and the private key is a 2048 bit RSA key.

The hybrid encryption scheme works but decrypting the symmetric keys is introducing a bottleneck into the application - decrypting one key is fine, but if I need to retrieve 100 records from the database and decrypt a field in them the script execution time is becoming a real issue because of the overhead decrypting the symmetric key adds. My unscientific tests using the speed tool in OpenSSL suggest that going from a 1024 bit RSA key to a 2048 RSA key is resulting in a decryption time seven times longer on my machine.

Is there a good reason why I can't just use a shared symmetric key (stored securely) to encrypt the symmetric keys for each record? I'm not entirely clear on what the benefit of using an asymmetric key scheme is. I understand that the RSA key can't be used to encrypt large amounts of data (which is why I'm using a symmetric key to do that) but is it the case that a symmetric key shouldn't be used to protect a small amount of data i.e. a 256 bit AES key?

Thanks in advance for any help or guidance!

Noel Whitemore
  • 627
  • 1
  • 9
  • 19
  • 1
    If you're using that strategy of key-per-record then yes, this could be slow. Do you have any other encryption libraries you can use that might perform better? – tadman Apr 03 '17 at 21:03
  • 2
    So, you're encrypting and decrypting your data in a PHP application. Where is the private key stored for decryption? If it is in the code or somewhere readable by the PHP code, you might as well drop RSA altogether and move to AES encryption of the AES keys. – Artjom B. Apr 03 '17 at 21:03
  • 1
    Asymmetric key scheme is great because you can share your public key with anyone without having to worry about encrypting the key. The key you can use to read your data (private key) is safe as long as you store it properly. I believe that you can use your symmetric keys as long as you store them properly. If it is an issue that the client can read the keys then you shouldn't worry, they can only decrypt their own data if they are truly unique. If you worr about a data breach, then consider private keys can be leaked in the same way. Just store them outside of the clients reach and will be ok – Robert I Apr 03 '17 at 21:10
  • Thanks for your input everyone :) tadman - Do you mean that I need to look at something other than RSA? I'm using the in-built PHP OpenSSL module although I can install other software on the server. Artjom - The private key is stored on the server and unlocked when the user logs-in. Technically, the private key will be held in memory for as long as the script execution takes to complete and whatever time it takes for PHP's garbage collector to remove it from memory. Robert - There's no distribution of data or keys, and the data doesn't need to be signed. – Noel Whitemore Apr 03 '17 at 21:14
  • I'm voting to close this question as off-topic because it's not really a programming question. – President James K. Polk Apr 03 '17 at 21:33
  • This question relates to the implementation of an encryption scheme in a PHP application, so I don't really see how it's not a programming question? Re-reading my question, what I was trying to say was this: if I use a symmetric key to protect another symmetric key, is it insecure to do so because of how little data is being encrypted? If I encrypt 32 bytes of data (i.e. a 256 bit AES key) with a 256 bit AES key, is that insecure? What about just 1 byte of data, is it secure? This is what I was trying to ascertain. – Noel Whitemore Apr 03 '17 at 21:50

1 Answers1

1

The irony of your question is that the use of a 2048-bit RSA key to encrypt a 256-bit AES key actually degrades the security -- see Table 1 (the difficulty to break an 88-bit symmetric key is about the same as the difficulty to break a 2054-bit RSA key)!

The benefit of public key cryptography for an application like this is when the decryption happens in an isolated place than the encryption. However, if they are both happening in the same place, then you are only making things worse by bringing in RSA. Instead, just stick with the AES.

TheGreatContini
  • 5,791
  • 1
  • 18
  • 25
  • Thanks for that - my knowledge of the way asymmetric schemes work is pretty basic so I'll need to read up on that. Is there any validity in the point I made about symmetric keys not being used to encrypt very small amounts of data? Assuming I used AES's CBC or CTR modes and only encrypt 1 byte of data, am I weakening the encryption because the only unique data is the initialisation vector and the single byte of data I'm encrypting or is the initialisation vector sufficient even with 0 bytes of data? – Noel Whitemore Apr 03 '17 at 22:25
  • 2
    @NoelWhitemore No you are not weakening it provided that you choose your IV securely and never repeat an IV -- read more about secure modes of operation [here](http://stackoverflow.com/a/42658861/3823831). However, be aware that the analysis of the AES indicates that it is very, very secure for encrypting large amounts of data under known plaintext and chosen plaintext attacks (amongst other types of attacks), and therefore you should not be afraid to encrypt large amounts of data with it. – TheGreatContini Apr 03 '17 at 22:44
  • Thanks again. If I can just ask one other question, I understand the reason for not reusing the IV but is there a recommended way to ensure that this never happens i.e. do I have to maintain a list of IVs for every piece of data I encrypt and then check against that list for new IVs, or is it statistically unlikely that exactly the same IV would be generated each time, assuming that the random data generator is cryptographically secure? – Noel Whitemore Apr 04 '17 at 09:30
  • 1
    IVs also need to be unpredictable. If you choose them via a cryptographic prng, then it is statistically extremely unlikely for a collision. – TheGreatContini Apr 04 '17 at 11:17
  • Ok thanks, I thought that might be the case. The way I'm generating my IVs at the moment is just by retrieving 16 bytes of data from /dev/urandom. – Noel Whitemore Apr 04 '17 at 11:39