I know there's little reason to still use
ENCRYPT() nowadays, what with
bcrypt being almost ubiquitous and MySQL providing better hashes such as
But while dabbling with
ENCRYPT() on MySQL 5.6.12 (OpenSuSE 13.1, x64), I noticed an anomaly with its output that I at first attributed to the entropy pool being depleted (it could have been), and then possibly to the salt being leaked between connections.
Upon verification, it turned out not to be the case.
Rather, the salt is derived from the UNIX timestamp. So two calls to
ENCRYPT() within the same second will yield identical salts, and the salt repeats itself exactly every one hour, 12 minutes, 16 seconds.
while(true); do \ echo "SELECT NOW(),ENCRYPT('test');" \ | mysql test | grep -v ENCRYPT; \ done | uniq -c 54 2014-05-14 00:13:16 w5kVzeZkJCcqM 148 2014-05-14 00:13:17 x5/h3KfsBkEYk 150 2014-05-14 00:13:18 y5thvRDxwJgM6 145 2014-05-14 00:13:19 z5RL9IZ0..XH6 141 2014-05-14 00:13:20 .6asQOJRqB1i2 130 2014-05-14 00:13:21 /6J1nHNWbi6Ac 124 2014-05-14 00:13:22 06NT9j.EegRJs
Of course I can supply my own salt and get it from a random source -
TO_BASE64(CONCAT(CHAR(RAND()*256),CHAR(RAND()*256))) or something, which should get the same character range as the original salt in its first two bytes, so
ENCRYPT()'s whipping up a salt of its own needs only be a last-ditch effort.
And the salt isn't expected to be secret, so it being known beforehand is maybe not too great a problem.
Even so, using
time() for salting doesn't seem a very good option to me (this answer also confirms this).
Am I missing something obvious? Is maybe this behaviour configurable somehow (apart from recompiling)? Is it a known feature (I wasn't able to find any reference on Google or MySQL KB)?