AES en-and decrypt PHP MySQL - php

Well, I definitively rightly chose my nick, as I am baffled over this:
First I encrypt it, and I get an encrypted row in my table. But when I try to decrypt it, I get zero rows as the result set.
Encrypting:
INSERT INTO accesobases (company, username,email) VALUES
('hola',
AES_ENCRYPT('pedro','capullo'),
AES_ENCRYPT('myemail',' capullo')
);
and when I run the decryption query, 0 rows show up.
SELECT company,
AES_DECRYPT('username', 'capullo'),
AES_DECRYPT('email', 'capullo')
from acceso
where company = 'hola';
Note that I did not encrypt company, but I will definitively need to, but I wanted to see where the error it could be. That is, not even departing from a non encrypted word (company = hola) I get any results. So, it will be even worse when I try to do as:
where AES_DECRYPT ('company', 'capullo') = ' " . $company . " '
which is how it would look like on my php pages. The above block was being run on the MySQL database itself.
So, the questions are two:
What is wrong with not showing any data
Whether the version of ..."$company.." will work.
However, if I say:
SELECT * from acceso
WHERE company = 'hola';
then, it does show the row with encrypted words
So, it is as if it did not have the time to decrypt the row before showing it and then shows nothing

SELECT company,
AES_DECRYPT('username', 'capullo'),
AES_DECRYPT('email', 'capullo')
from acceso
where company = 'hola';
This won't work because you're telling MySQL to decrypt the constant string "username", not the value of the username column. Remove the quotes on 'username' and 'email'.
where AES_DECRYPT ('company', 'capullo') = ' " . $company . " '
Same issue here. However, it'd be more efficient to do this the other way around in order to leverage indices:
where company = AES_ENCRYPT(?, 'capullo')
That being said, using AES_ENCRYPT on the MySQL server side is NOT SECURE. The encryption key is passed to the server with each query, and, as such, will appear in the MySQL processlist, as well as potentially in server query, slow, and/or error logs; if you are not using SSL for your MySQL connection, they will be passed over the network in cleartext, as will the decrypted data.

These are column names, so don't put them in quotes:
AES_DECRYPT('username', 'capullo'),
AES_DECRYPT('email', 'capullo')
Do this instead:
AES_DECRYPT(username, 'capullo') AS username,
AES_DECRYPT(email, 'capullo') AS email
Also, since the output of AES_ENCRYPT is binary, ensure your columns are binary.
It also looks like you might have two different tables, 'accesobases' and 'acceso', so ensure you're using the correct table.
Your statement:
where AES_DECRYPT (company, 'capullo') = ' " . $company . " '
Seems fine, as long as you remove the quotes from the column name here too. It will be slow since it won't be able to use an index. Instead, you should do this:
where company = AES_ENCRYPT('$company', 'capullo')

Related

Is This a Bug in MySQL?

I am using mysql and php (Laravel) and facing a very strange situation .
I am trying get an encrypted user type and user id and decrypt it . and then find the records for that user id .
my code is like this . i am using Laravel framework .
$key = Config::get('app.key');
$decodedUserIDwithType = base64_decode($encryptedUserIDwithType);
$decryptedUserIDwithType = mcrypt_decrypt(XXXXX , $key, $decodedUserIDwithType, XXXXXX);
$userIDwithType = $decryptedUserIDwithType;
I am expecting the decoded value to be something like this
id#100
so i will explode it by # and find the user id , here it is 100 .
for testing i have changed the encrypted value by manually adding one or two characters . when i decrypt i got something like
id#100������������������������]u甀�+&�fj�W�ZЪS��d��]3�]"
and after i explode this i will get the id as 100���]u甀�+&�fj�W�ZЪS��d��]3�]"
now i select all raws with same id using .
SELECT * FROM table WHERE id=$id
it will select the recordes with id = 100 even the actual id is 100���]u甀�+&�fj�W�ZЪS��d��]3�]"
so weird . the type of the id column is INT may be that is why it is matched .
but from my point of view it is very bad , because my whole logic got incorrect because of this .
I checked this query both in Laravel and raw MySQL Query , the results are the same .
Any Ideas , Thanks in advance .
UPDATE
I understand the point mentioned by Shadow, but how to handle a
scenario like this , from decryption i expect id like 100 , but if i
got something like 1ASASAS, if you cast it to int it will be 1 (this
is just for example) . now the problem is my database has a user id 1
also , so now you can see how much trouble i am in because i will get an
incorrect user , sadly this is related to payment :P . some incorrect
users wallet will be topped up . ha ha .how to handle this
This is not a bug, this is a feature in MySQL described in Type Conversion in Expression Evaluation section of the MySQL manual:
When an operator is used with operands of different types, type conversion occurs to make the operands compatible. Some conversions occur implicitly. For example, MySQL automatically converts numbers to strings as necessary, and vice versa.
When MySQL converts a string to a number, it evaluates the characters starting from the left as long as the characters can be interpreted as part of a number and stops, if it encounters a character that cannot be considered as part of a number. In case of 100���]u甀�+&�fj�W�ZЪS��d��], the first � cannot be interpreted as a part of the number, so MySQL stops after 100. The characters after 100 seem to be some kind of garbage anyway and you should check your php code why it produces that garbage.

mssql where md5(tablefield) = md5value?

I usually don't work with MSSQL and wonder how i can match a md5 value of a field value stored as string.
In mysql i would use
SELECT * FROM table WHERE md5(field) = $md5value
but i can't find a simple solution for this in mssql.
Now i loop all posts and check for the matched value in the loop, but this is way to slow.
How do I solve this in MSSQL?
I have no possibility to add a extra field in the table and store the md5 value, so i have to do the check this way.
Using odbc driver in php.
MSSQL uses no MD5(), but a function called HASHBYTES:
SELECT * FROM table WHERE HASHBYTES('MD5',field) = $md5value
This function appends '0x' to the hash though, so to fully check it, you need:
SELECT * FROM table WHERE HASHBYTES('MD5',field) = '0x' . $md5value
Edit: in PHP, it looks like this:
$query = "SELECT * FROM table WHERE HASHBYTES('MD5',field) = \"0x" . $md5value . '"';

How can I send a PHP variable array to a MySQL database?

So I have a variable array created from scraping a plaintext data string from a webpage (using Simple HTML DOM Parser class). This variable is the formatted to make it more concise and useful.
I now wish to export this data into a MySQL table where the table name is the webpage title (scraped separately) and the data input is an array, where each word extracted from the webpage is a separate data record.
Here is my code (where $trimmed is a formatted variable string of data scraped from a user input webpage):
$trimmed->plaintext=trim($trimmed->plaintext);
$array = (explode(" ", $trimmed->plaintext));
$printarray = print_r ($array);
mysql_select_db("test", $connect) or die ('Could not find database.');
$sql = "CREATE TABLE '$title'";
$myquery = sprintf("INSERT INTO WebPage '%s'
VALUES '%s'",
mysql_real_escape_string($title->plaintext),
mysql_real_escape_string($printarray));
$result = mysql_query($myquery);
if (!$result) {
$message = '<br /><br /><br /> Invalid query: ' . mysql_error() . "\n";
$message .= '<br /><br /> Whole query entered here: ' . $myquery;
die($message);
}
The error is recieve when trying this is:
Invalid query: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''Example Domain' VALUES '1'' at line 1
Whole query entered here: INSERT INTO WebPage 'Example Domain' VALUES '1'
I can provide more code if needed, and sorry in advance if I haven't explained this very well; I am quite new to this.
Thanks in advance.
Your SQL:
INSERT INTO WebPage 'Example Domain' VALUES '1'
is not valid. Maybe you meant:
INSERT INTO `WebPage` ('Example Domain') VALUES ('1')
On a side note, if Example Domain is indeed a column name: you should really avoid spaces in field's names.
There are lot's of errors here.
First, The SQL you're generating for the insert looks incorrect:
INSERT INTO tableName (fields) VALUES (values)
Your code says:
INSERT INTO WebPage 'plainText' VALUES (array)
You should remove Webpage if you want to create a table named like the webpage title. Plus, it must be a single word (replace empty spaces with something like '_').
Second, you need to create the table. You need the proper CREATE TABLE structure prior to doing the insert.
Third, your echo print_r won't work for inserting a value per field (column). You need to iterate the array and for each key insert a value. But you should had already done this for creating the table columns.
It looks as if you are trying to incorporate the output from print_r in your query. This isn't possible as print_r is a function that outputs data from an array to the page.
In order to store the contents of an array in the database you can use json_encode to convert the array to a string. Then use json_decode when retrieving it so change it back into a php array.
E.g.
$myquery = sprintf("INSERT INTO `WebPage` ('%s')
VALUES ('%s')",
json_encode($title->plaintext),
json_encode($array)); //not $printarray as that is not an actual array
edit: As others have noted, mysql_real_escape_string is a deprecated function so other methods should be used to escape characters.
edit2: serialize could also be used in place of json_encode although I am not sure of the relative advantages/disadvantages. A more ideal method would be to restructure your database table to accommodate all contents of the array as a separate piece of data although this may sometimes not be practical.

How to Handle (Escape) a % sign in mysqlclient (C Library)

i am using mysqlclient,
in one of my query, as shown below
sprintf (query, "select user from pcloud_session where id = '%s'", sid);
here some time this sid is with % sign in it like the example
2Cq%yo4i-ZrizGGQGQ71eJQ0
but when there is this % this query always fail, i think i have to escape this %, but how ?
i tried with \ and %% , but both of this not working, please help me here
UPDATE:
When using session.hash_bits_per_character = 6, in php session ,the default charset contains a character (comma) that will always be urlencoded(here it is %2C). This results in cookie values having this %2C in it, but session db having a comma instead of it. any idea about fixing this problem ?.. sorry for the confusion
Thanks
There's no need to escape a literal '%' in MySQL query text.
When you say the query "always fail", is it the call to the mysql_query function that is returning an error? Does it return a SQL Exception code, or is it just not returning the resultset (row) you expect?
For debugging, I suggest you echo out the contents of the query string, after the call to sprintf. We'd expect the contents of the string to be:
select user from pcloud_session where id = '2Cq%yo4i-ZrizGGQGQ71eJQ0'
And I don't see anything wrong with that SQL construct (assuming the id column exists in pcloud_session and is of character datatype. Even if id was defined as an integer type, that statement wouldn't normally throw an exception, the string literal would just be interpreted as integer value of 2.)
There should be no problem including a '%' literal into the target format of an sprintf. And there should be no problem including a '%' literal within MySQL query text.
(I'm assuming, of course, that sid is populated by a call to mysql_real_escape_string function.)
Again, I suggest you echo out the contents of query, following the call to sprintf. I also suggest you ensure that no other code is mucking with the contents of that string, and that is the actual string being passed as an argument to mysql_query function. (If you are using the mysql_real_query function, then make sure you are passing the correct length.)
UPDATE
Oxi said: "It does not return a SQL Exception code, it just does not return the result[set] I expect. I did print the query, it prints with % in it."
#Oxi
Here's a whole bunch of questions that might help you track down the problem.
Have you run a test of that query text from the mysql command line client, and does that return the row(s) you expect?
Is that id column defined as VARCHAR (or CHAR) with a length of (at least) 24 characters? Is the collation on the column set as case insensitive, or is it case sensitive?
show create table pcloud_session ;
(I don't see any characters in there that would cause a problem with characterset translation, although that could be a source of a problem, if your application is not matching the database charactarset encoding.)
Have you tested queries using a LIKE predicate against that id column?
SELECT id, user FROM pcloud_session WHERE id LIKE '2Cq\%yo4i-%' ESCAPE '\\'
ORDER BY id LIMIT 10 ;
SELECT id, user FROM pcloud_session WHERE id LIKE '2Cq%'
ORDER BY id LIMIT 10 ;
Are you getting no rows returned when you expect one row? Are you getting too many rows returned, or are you getting a different row than the one you expect?
That is an oddball value for an id column. At first, it looks almost as if the value is represented in a base-64 encoding, but it's not any standard encoding, since it includes the '%' and the '-' characters.
If you're going to do this in C without an interface library, you must use mysql_real_escape_string to do proper SQL escaping.
There shouldn't be anything intrinsically wrong with using '%inside of a string, though, as the only context in which it has meaning is either directly inprintftype functions or as an argument toLIKE` inside of MySQL.
This proves to be really annoying, but it's absolutely necessary. It's going to make your code a lot more complicated which is why using low-level MySQL in C is usually a bad idea. The C++ wrapper will give you a lot more support.
You really shouldn't escape the string yourself. The safest option is to let the MySQL API handle it for you.
For a string of maximum length n, start by allocating a string of length 2*n+1:
int sidLength = strlen(sid);
// worst-case, we need to escape every character, plus a byte for the ASCIIZ
int maxSafeSidLength = sidLength * 2 + 1;
char *safeSid = malloc(maxSafeSidLength);
// copy "sid" to "safeSid", escaping as appropriate
mysql_real_escape_string(mysql, safeSid, sid, sidLength);
// build the query
// ...
free(safeSid);
There's a longer example at the mysql_real_escape_string page on dev.mysql.com, in which they build the entire query string, but the above approach should work for supplying safeSid to sprintf.

Mysql query advice/help needed

I am building a site where candidates can post their resume and employers can post their jobs.
The employers can post a job with multiple qualifications and I saved it in database like this PHP,Javascript,ASP. Now I want admin to be able to select the candidates who are eligible for a post.
I have written the query:
$sql = "
SELECT
cand_f_name,
cand_l_name,
cand_qualification,
cand_phone,
cand_email,
cand_experience_yr,
cand_experience_mn,
cand_message,
cand_id
FROM
tbl_cand_data
WHERE
cand_qualification LIKE '%$emp_q%'
But it is not showing the expected result. I think my condition cand_qualification LIKE '$emp_q' is wrong.
My tbl_cand_data :
If you are doing a LIKE query you should include wildcards, as they will match a string containing, otherwise just do an exact match using =:
// String match
WHERE
cand_qualification LIKE '%emp_q%';
// Exact match
WHERE
cand_qualification = '$emp_q';
// You could try a WHERE IN clause as well
WHERE cand_qualification IN ('$emp_q');
// Values have to be quoted individually
WHERE cand_qualification IN ('BA','BSc','BCom');
// If you have an array you can do this:
$myArray = array('BA', 'BSc', 'BCom');
$emp_q = "'" . implode("','", $myArray) . "'"; //Output 'BA', 'BSc', 'BCom'
I saved it in database like this PHP,Javascript,ASP
That's what you did utterly wrong.
you have to create a related table (that's why our ratabase called relational one!) storing qualifications, and interconnection table, consists of qualifications id linked with candidates ids.
And query them using basic joins.
Note that despite of your current decision, even if you decide to continue with your lame schema, you WILL have to remake it proper way, sooner or later (but sooner will make you less work).
That is the very basics of database architecture and noone can go against it.
SELECT fields FROM tbl_cand_data d, qualification q, qual_cand qc
WHERE q.name = 'ASP' AND q.id=qc.qid AND d.id=qc.did
Like requires percent %
try it

Categories