It sounds like you might want to do some more background on crypto generally, and DB encryption options specifically (you don't mention the data store, but there are MySQL and Postgres options for full encryption). In general, it is almost always a bad idea to "roll your own", and unfortunately, between mcrypt() and openssl_*() functions, there are frankly too many options presented to a novice (such as presenting EBC and CBC as equally valid options). While this thread: https://security.stackexchange.com/questions/18197/why-shouldnt-we-roll-our-own is mainly talking about the futility of creating "novel" cryptographic primitives, the principle also applies to naive attempts at implementing application- and database-level encryption as well.
As a practical matter, the most challenging thing you will likely have to deal with is the issue of password/key management. The code below puts all of the responsibility on the client (sender) - and unless you save the submitted password (which sort of defeats the whole purpose), if the user forgets or is otherwise unable to supply their password in the future, encrypted data in the database will be unrecoverable. (And, yes, if you really want to go down the Yak Shaving path, there are options for multi-key envelope encryption).
If you store the key/password server-side you are, at best, only putting a small road bump in the path of an adversary: if she can manage to read your key file, she can retrieve the data. But worst, by saving the password locally, you are giving a false sense of security to your users, and if this is financial, health, or otherwise protected information, you and your organization take on that burden of that liability.
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 the code generator). For password hashing, take a close look at the phpPass library here: http://www.openwall.com/phpass/.
All that said, here is a working start for simple two-way, reasonably strong encryption, with randomly generated initialization vectors and salts, and a 256-bit AES symmetric (e.g., non-public key) cipher. Tested on OSX Lion & 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's 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 retrieve 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";
Sample output:
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