Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I am using MySQL AES_ENCRYTP() and AES_DECRYPT() to store sensitive details in a database, and currently storing the key in a php file outside of the web root with read access only. The key file looks like:

<?php
    define("CRYPTO_KEY", "SOME-LONG-KEY-HERE");
?>

After further reading, people recommend that the key should ONLY exist in memory and to use something like Shamir's Secret Sharing WikiPedia article.

How would this work in my case with php, and where in memory would the key be stored?

Thanks for the help.

share|improve this question

2 Answers 2

Application written in PHP can be made memory persistent, i.e. run as a service and respond to requests of another local process that is or isn't persistent, for example by using FastCGI Process Manager. I'm not some PHP guru, but the FastCGI modules are standard across many platforms that I've worked with before, so it should be much the same. In a nutshell, using FastCGI you should be able to run a memory persistent service (or an Apache worker) that listens on a specific port for HTTP requests and sends HTTP responses back to the caller web application. So this is how I'd go about writing your Shamir's Secret Sharing:

Write a memory-persistent key server PHP application that will take some password (key A) as an input from the caller web application, and another password (key B) that you enter during key server application's initialization. You can make entering this key B remote enabled or local only, but that can be made with the same password entry form and just setup your firewall accordingly to your needs. Then concatenate these two keys A+B and hash this value (say bcrypt, what's in PHP named as CRYPT_BLOWFISH, either case use a slow hashing algorithm for added protection against brute-force attacks) to get the key C that you'll use to decrypt an AES encrypted database key D stored in a local file. Drop (overwrite with random nonsense or nullify) your key B variable, but keep key A and key C in memory.

You will use key A to check subsequent local requests of your non-persistent web application (you can hash this value, but using a slow hashing algorithm doesn't make much sense with frequent requests, and fast hashing algorithms won't help much), and use key C to decrypt locally stored database key D that you need to send back to the authenticated web application. Host this key server application as a FastCGI Apache worker, set the port at which it is to respond to HTTP requests (not HTTP(S) ports 80, 8080, or 443), and configure your firewall to only respond to remote requests on this selected port for the key B input URL, while the database key D retrieval URL should only be accessible locally on the same web server.

Then generate your encrypted database key file. Decide on two random passwords key A and key B, generate key C as a bcrypt hash of the two concatenated keys A+B, and use this key C to AES encrypt your database key D, and store it in a locally accessible file. Store key A, as you'll be using it in your PHP written web applications to retrieve, and memorize or otherwise safely store key B. Password protect / encrypt your database using key D and you're good to go.

This approach is in essence a 2FA, where the database key is only ever kept in memory, or strongly encrypted in a local file, and the decryption key is never sent in its entirety by a single mode of input. If the attacker gets a hold of all but a single part of this key chain, or even create a complete copy of your web server hosted files, applications, and the database, he wouldn't be able to decrypt your database. Provided of course, your approach is sound, and uses strong encryption and password hashing algorithms.

share|improve this answer

You're asking a couple questions here, one about AES and another about secret sharing schemes. They're orthogonal technologies, so theoretically you can encrypt the key file using AES [with a different key] and share the result using a secret-sharing scheme. It seems like a key wrap scheme might be along the lines of what you're looking for. But then the question becomes how to store the key-encrypting key, etc.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.