Reputation: 2015
I'm having an issue with an encryption script I wrote. I have hundreds of inputs, and therefore I used a bucket sorting algorithm as an "in-script" database in order to avoid the hassle of dealing with hundreds of MySQL columns, not to mention it saves on code space. The data is stored in one column in an SQL database. Entries are separated by '
and variables in that entry are separated by >
. That is why I am string replacing the final result of the encryption...to avoid producing extra deliminators.
ENCRYPT:
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM);
$key = pack("H*", "**64CharacterStringHere**");
$value = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $value, MCRYPT_MODE_CBC, $iv);
$value = $iv . $value;
$value = str_replace (">", "9Y6SnNmOBl", $value);
$value = str_replace ("'", "SxsNEpBe18", $value);
DECRYPT:
$value = str_replace ("9Y6SnNmOBl", ">", $value);
$value = str_replace ("SxsNEpBe18", "'", $value);
$iv = substr($value, 0, 16);
$value = substr($value, 16);
$key = pack("H*", "**64CharacterStringHere**");
$value = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $value, MCRYPT_MODE_CBC, $iv);
If I ommit this snippet from my code, it works perfectly. Data is displayed and saved normally. However, if I add this code sometimes data simply won't be saved, and if it is at least one variable doesn't get decrypted for some reason, even though I'm 100% sure the function is being run on each variable, because the function does more than just encrypt and decrypt.
I'm completely stumped as to why this is happening.
MySQL Query:
$new_accountant = "'" . $var_1 . ">" . $var_2;
$new_string = $string . $new_accountant;
$new_entry_query = 'UPDATE phone_tree SET string="' . $new_string . '" WHERE id="' . $userid . '";';
mysql_query($new_entry_query);
In the above script, $string
is defined by a MySQL query which gets the current value of the column which contains all the data thus far.
I'm messing around with it right now. It doesn't save at all about half the time, and when it does get saved, variables don't get decrypted correctly about half the time.
I suspect it's something pertaining to how I'm storing the IV...which is with the variable, but I don't know how what I'm doing is an issue.
Upvotes: 1
Views: 563
Reputation: 108806
It looks to me like your MySQL string
column is defined with a varchar(nnn)
data type. Is that correct?
If so, I suggest you base-64 encode your encrypted material before storing it into MySQL, and base-64 decode it afterward? This is common practice in the transmission and storage of encrypted information. It makes your material string-safe. MySQL may be bashing your binary data.
The base-64 character set (used by the MIME version of base-64 implemented in php) includes only 7-bit ASCII characters. It includes the digits, upper- and lower- case letters, and the characters +
/
=
. That's good because the delimiters you've chosen (>
'
) won't show up in the encoded text, so you can get rid of your symbol-stuffing str_replace ("9Y6SnNmOBl", ">", $value)
code.
Do this while you're encoding, and skip the symbol-stuffing.
$value = base64_encode($iv . $value);
Do this while you're decoding, and skip the symbol unstuffing.
$value = base64_decode($value);
$iv = substr($value, 0, 16);
$value = substr($value, 16);
This makes your encrypted data about 1.3 times larger than it otherwise would be. That's not much at modern mass storage prices, and a reasonable price to pay for simplicity. If it presents an insurmountable cost obstacle, you can investigate compressed row formats in MySQL.
Upvotes: 2