Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

problem encrypting data (AES_ENCRYPT/AES_DECRYPT)

615 views
Skip to first unread message

ViVi

unread,
May 30, 2013, 2:28:32 AM5/30/13
to
This is driving me crazy !
I'm getting a string from the user (form,input,type=text)
I escape it (mysql_real_escape_string)
And write it encrypted to DB (AES_ENCRYPT).
Then I read it back (SELECT AES_DECRYPT).
It works 99.99 % of the time.
"Sometime" it fails: i.e. the read value is NOT = to the written one.
To be more specific: the "encrypted" value (select 'catName') contains
something, the decrypted one ( SELECT AES_DECRYPT(`catName`...)
contains garbage.
I've not been able to track down WHEN it fails, but some strings
everytime fail, other strings are OK.
OK are .... almost all
the following string
doppio " apice
FAILS everytime.
I've tried defining the DB field (catName) VARCHAR or BINARY to no
avail.
I dont thing it's a "quote" problem, because if I dont encrypt/decrypt
the string all works fine.
Can someone help me ?
TIA

... get data from user:
echo " <form action=\"thisScript.php\" name='theName' method=\"post\">
\n";
echo "<input name=\"cat\" type=\"text\" value=\"\" maxlength=\"20\"
size=\"20\" >\n";
echo "<br><INPUT type=\"submit\" style=\"height: 25px; width: 100px\"
value=\"GO\"><br><br>";
... connect & select DB
... Write to DB
$s_="SALT";
$cat=$_REQUEST['cat'];
$cat=mysql_real_escape_string($cat);
mysql_query("INSERT INTO `tableName` (`catName`) VALUES
( AES_ENCRYPT('$cat' , '$s_') )");
$rc_=mysql_insert_id();
... read it from DB
$rlib=mysql_query("SELECT AES_DECRYPT(`catName`, '".$s_."') as cate
FROM `tableName` where `cat_idx` = ".$rc_."")or die(mysql_error());
$myrow = mysql_fetch_array($rlib);
$out=$myrow['cat'];
if ( $out != $_REQUEST['cat'] ) echo "<br><br><b>BAD !</b><br><br>";

Denis McMahon

unread,
May 30, 2013, 3:46:05 AM5/30/13
to
On Wed, 29 May 2013 23:28:32 -0700, ViVi wrote:


> I've not been able to track down WHEN it fails, but some strings
> everytime fail, other strings are OK.

How long are the strings that fail - I seem to recall that aes works on
128 bit chunks - so multiples of 16 bytes.

One padding scheme I have seen uses n digits of hex character n as
padding, with 16 wrapping to 0, so for example if the data is a multiple
of 16 bytes, the last 16 bytes are 0, but then if the length of the data
mod 16 is:

1 - 15 * f
2 - 14 * e
...........
15 - 1 * 1
0 - 16 * 0

Then after you decrypt, remove the padding chars, given that the last
char tells you how much padding there is.

> OK are .... almost all the following string doppio " apice FAILS
> everytime.
> I've tried defining the DB field (catName) VARCHAR or BINARY to no
> avail.

Also, there's a suggestion elsewhere that I googled that the sql data
field should be varbinary or blob. Is it possible that your encrypted
data is longer than your fixed width field, or in some cases not
compatible with varchar?

--
Denis McMahon, denismf...@gmail.com

The Natural Philosopher

unread,
May 30, 2013, 4:21:53 AM5/30/13
to
definitely you should use varbinary or blob

"

|AES_ENCRYPT()|
<https://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html#function_aes-encrypt>
encrypts a string and returns a binary string. |AES_DECRYPT()|
<https://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html#function_aes-decrypt>
decrypts the encrypted string and returns the original string. The input
arguments may be any length. If either argument is |NULL|, the result of
this function is also |NULL|.

Because AES is a block-level algorithm, padding is used to encode uneven
length strings and so the result string length may be calculated using
this formula:

16 * (trunc(/|string_length|/ / 16) + 1)

If |AES_DECRYPT()|
<https://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html#function_aes-decrypt>
detects invalid data or incorrect padding, it returns |NULL|. However,
it is possible for |AES_DECRYPT()|
<https://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html#function_aes-decrypt>
to return a non-|NULL| value (possibly garbage) if the input data or the
key is invalid."

https://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html


--
Ineptocracy

(in-ep-toc’-ra-cy) – a system of government where the least capable to lead are elected by the least capable of producing, and where the members of society least likely to sustain themselves or succeed, are rewarded with goods and services paid for by the confiscated wealth of a diminishing number of producers.

ViVi

unread,
May 30, 2013, 4:58:01 AM5/30/13
to
Thanks to you and to Denis for your patience.
Unfortunately nor varbinary nor blob helped me.
About the padding:
And nothing changes if the string is 16 (or 15 or 14 for cf/lf) bytes
long
doppio apice " f
....+....0123456 ... and variations

Doug Miller

unread,
May 30, 2013, 6:53:52 AM5/30/13
to
ViVi <vincenz...@gmail.com> wrote in news:3bfd0bde-1d5d-45eb-afe9-
9728dc...@l3g2000vbl.googlegroups.com:
Aside from all that, why are you decrypting it in the first place? You may not need to.

Specifically, if the objective is to determine whether a password entered by a user matches
the [encrypted] password stored in your database, the proper way to do this is not to
DEcrypt the stored password and compare it to the entered password, but to ENcrypt the
*entered* password and compare the encrypted versions.

ViVi

unread,
May 30, 2013, 7:53:29 AM5/30/13
to
On 30 Mag, 12:53, Doug Miller <doug_at_milmac_dot_...@example.com>
wrote:
> Aside from all that, why are you decrypting it in the first place? You may not need to.
>
> Specifically, if the objective is to determine whether a password entered by a user matches
> the [encrypted] password stored in your database, the proper way to do this is not to
> DEcrypt the stored password and compare it to the entered password, but to ENcrypt the
> *entered* password and compare the encrypted versions.
I'm not encrypting passwords ...
I'm encrypting really sensible data blah blah blah ;-)
Thankyou anyway for your attention !

Jerry Stuckle

unread,
May 30, 2013, 8:09:04 AM5/30/13
to
On 5/30/2013 2:28 AM, ViVi wrote:
> This is driving me crazy !
> I'm getting a string from the user (form,input,type=text)
> I escape it (mysql_real_escape_string)
> And write it encrypted to DB (AES_ENCRYPT).
> Then I read it back (SELECT AES_DECRYPT).
> It works 99.99 % of the time.
> "Sometime" it fails: i.e. the read value is NOT = to the written one.
> To be more specific: the "encrypted" value (select 'catName') contains
> something, the decrypted one ( SELECT AES_DECRYPT(`catName`...)
> contains garbage.
> I've not been able to track down WHEN it fails, but some strings
> everytime fail, other strings are OK.
> OK are .... almost all
> the following string
> doppio " apice
> FAILS everytime.
> I've tried defining the DB field (catName) VARCHAR or BINARY to no
> avail.
> I dont thing it's a "quote" problem, because if I dont encrypt/decrypt
> the string all works fine.
> Can someone help me ?
> TIA
>
<snip code>


Vivi,

Since your problem seems to be with the MySQL functions, you'll probably
get better help in comp.databases.mysql, where the MySQL experts hang out.


--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstu...@attglobal.net
==================

The Natural Philosopher

unread,
May 30, 2013, 8:52:31 AM5/30/13
to
yep...I did that when taking credit card details. The data was on a usb
stick. The SEED was on the computer. When unattended, they were separated..

ViVi

unread,
May 30, 2013, 10:05:14 AM5/30/13
to
> Vivi,
> Since your problem seems to be with the MySQL functions, you'll probably
> get better help in comp.databases.mysql, where the MySQL experts hang out.

You're right, it's a mysql problem.
Thank you for your help
Vivi

mysql> truncate table `ex_categoria_master` ;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO `ex_categoria_master` (`categoria_nome`) VALUES
( AES_ENCRYPT('doppio apice " f','SALT') );
Query OK, 1 row affected, 1 warning (0.02 sec)

mysql> SELECT AES_DECRYPT(`categoria_nome`, 'SALT') as bunny ,
`categoria_nome` FROM `ex_categoria_master` where `categoria_idx` = 1;
+-------+--------------------------------+
| bunny | categoria_nome |
+-------+--------------------------------+
| NULL | gð]q’3$Û í¹-) £•…É0³ „¬^ }ü |
+-------+--------------------------------+
1 row in set (0.00 sec)

mysql> select categoria_idx , `categoria_nome` from
ex_categoria_master;
+---------------+--------------------------------+
| categoria_idx | categoria_nome |
+---------------+--------------------------------+
| 1 | gð]q’3$Û í¹-) £•…É0³ „¬^ }ü |
+---------------+--------------------------------+
1 row in set (0.00 sec)

The Natural Philosopher

unread,
May 30, 2013, 10:34:29 AM5/30/13
to
please show results of:

show fields in ex_categoria_master;

ViVi

unread,
May 30, 2013, 10:38:14 AM5/30/13
to
i'm definetly a moron:
i've defined the encrypted field too short:
`categoria_nome` varbinary(30) DEFAULT NULL,
and every string longer than 15 chars was corrupted.
...
..
.
sorry for the disturb, and please don't be too rude
:-(

The Natural Philosopher

unread,
May 30, 2013, 10:57:37 AM5/30/13
to
ah...NO COMMENT

Arno Welzel

unread,
Jun 5, 2013, 8:51:55 AM6/5/13
to
Nobody's perfect ;-)

JFTR:

<http://dev.mysql.com/doc/refman/4.1/en/encryption-functions.html#function_aes-encrypt>

Cite:

"Because AES is a block-level algorithm, padding is used to encode
uneven length strings and so the result string length may be calculated
using this formula:

16 * (trunc(string_length / 16) + 1)

If AES_DECRYPT() detects invalid data or incorrect padding, it returns
NULL. However, it is possible for AES_DECRYPT() to return a non-NULL
value (possibly garbage) if the input data or the key is invalid."


--
Arno Welzel
http://arnowelzel.de
http://de-rec-fahrrad.de
0 new messages