It looks like you might want to make some more background on crypto in the general case and on the database encryption options (you did not mention the data store, but there are MySQL and Postgres options for full encryption). In general, it is almost always a bad idea to "collapse your own," and, unfortunately, between the mcrypt () and openssl _ * () functions there are frankly too many options presented to beginners (for example, the EBC and CBC views are equally valid parameters) . Although this thread: https://security.stackexchange.com/questions/18197/why-shouldnt-we-roll-our-own- basically speaks of the futility of creating "new" cryptographic primitives, this principle also applies to naive attempts to implement the level application and database encryption as well.
As a practical matter, the most difficult task you will probably have to deal with is the problem of managing passwords / keys. The code below puts all responsibility on the client (sender) - and if you do not save the password provided (what kind of defeat of the target), if the user forgets or cannot provide his password in the future, the encrypted data in the database will not be recoverable. (And yes, if you really want to go down the Yak Shaving path, there are options for encryption using multiple keys).
If you store a server server with a key / password, you, at best, only put a small road track in the path of the enemy: if she manages to read your key file, she will be able to receive data. But worst of all, by storing the password locally, you give a false sense of security to your users, and if this is financial, medical, or other secure information, you and your organization take on this responsibility.
Finally, there is a mature library here: http://phpseclib.sourceforge.net/crypt/examples.html , but, in my opinion, it offers too many options for a novice user (see, for example, the default EBC mode in code generator). For password hashing, carefully check out the phpPass library here: http://www.openwall.com/phpass/ .
All that is said here is a working start for simple two-way reasonably reasonable encryption with random generated vectors and initialization salts and a 256-bit AES-symmetric (for example, non-public key) cipher. Tested on OSX Lion and CentOS / RedHat 6.
Good luck
//$message = escapeshellarg( $_POST['message'] ); $message = 'This is my very secret data SSN# 009-68-1234'; // Set to some reasonable limit for DB. // Make sure to size DB column +60 chars $max_msg_size = 1000; $message = substr($message, 0, $max_msg_size); // User password (swap for actual form post) //$password = escapeshellarg( $_POST['password'] ); $password = 'opensesame'; // Salt to add entropy to users' supplied passwords // Make sure to add complexity/length requirements to users passwords! // Note: This does not need to be kept secret $salt = sha1(mt_rand()); // Initialization Vector, randomly generated and saved each time // Note: This does not need to be kept secret $iv = substr(sha1(mt_rand()), 0, 16); echo "\n Password: $password \n Message: $message \n Salt: $salt \n IV: $iv\n"; $encrypted = openssl_encrypt( "$message", 'aes-256-cbc', "$salt:$password", null, $iv ); $msg_bundle = "$salt:$iv:$encrypted"; echo " Encrypted bundle = $msg_bundle \n\n "; // Save it... (make sure to use bind variables/prepared statements!) /* db_write( "insert into sensitive_table encrypted_msg values (:msg_bundle)", $msg_bundle ); */
Now return it:
// Retrieve from DB... //$password = escapeshellarg( $_POST['password'] ); $password = 'opensesame'; // Swap with actual db retrieval code here //$saved_bundle = db_read( "select encrypted_msg from sensitive_table" ); $saved_bundle = $msg_bundle; // Parse iv and encrypted string segments $components = explode( ':', $saved_bundle );; var_dump($components); $salt = $components[0]; $iv = $components[1]; $encrypted_msg = $components[2]; $decrypted_msg = openssl_decrypt( "$encrypted_msg", 'aes-256-cbc', "$salt:$password", null, $iv ); if ( $decrypted_msg === false ) { die("Unable to decrypt message! (check password) \n"); } $msg = substr( $decrypted_msg, 41 ); echo "\n Decrypted message: $decrypted_msg \n";
Output Example:
Password: opensesame Message: This is my very secret data SSN# 009-68-1234 Salt: 3f12ce187d5c5bcc3b0d5acf1e76fad8b684ff37 IV: 00c1d3b4c6a6f4c3 Encrypted bundle = 3f12ce187d5c5bcc3b0d5acf1e76fad8b684ff37:00c1d3b4c6a6f4c3:KB6k+GlM+0EHbETUgEe8Lck0nF5qBz+51wc5LtmS4XMOm0Pfyyr2PIXMVEyzs/41 array(3) { [0]=> string(40) "3f12ce187d5c5bcc3b0d5acf1e76fad8b684ff37" [1]=> string(16) "00c1d3b4c6a6f4c3" [2]=> string(64) "KB6k+GlM+0EHbETUgEe8Lck0nF5qBz+51wc5LtmS4XMOm0Pfyyr2PIXMVEyzs/41" } Decrypted message: This is my very secret data SSN# 009-68-1234