I wish to encrypt/decrypt data in my MySQL database stored on my server. I use a salted hash for my passwords. All encryption/decryption would occur on the server. I use PHP end points which my remote clients access. The end points then access the MySQL database.
I've got the following PHP code to cipher/decipher a message:
<?php
$key = "mySecretKey";
$cipher = "aes-128-gcm";
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext = openssl_encrypt("message to be encrypted", $cipher, $key, $options=0, $iv, $tag);
$original_plaintext = openssl_decrypt($ciphertext, $cipher, $key, 0, $iv, $tag);
echo "original message: ".$original_plaintext."\n";
// $iv and $tag change each time we encrypt the data, so store these
?>
... which I was going to use to store encrypted data in my database. However, I will also need to store $iv
and $tag
with my data as these change for each openssl_encrypt
executed.
On the other hand, I could just use MySQL's AES_ENCRYPT
functions. This option would much simplify my code, because I can just add AES_ENCRYPT(data, key)
to my SQL code.
However, I get the feeling the PHP solution is more secure than AES_ENCRYPT
alone. Is this true?
On the other hand, I'm not so sure. For example, if somebody got hold of my AES_ENCRYPT
key, then they could quite as easily get hold of my PHP $key
in which case they would also be able to decrypt the openssl_encrypt
-ed messge too, since the $iv$
and $tag
information would probably be as easy to get hold of if they've got their hands on the $key
somehow.
Or maybe I'm going about my PHP solution the wrong way. Maybe $iv
should not be generated each time encrypt a piece of information? Maybe $iv
should be final, i.e. always the same, in which case $tag
is always the same...