2

does using a hash on a value before inserting it into an SQL query protect against sql injection without even having to use mysql_real_escape_string? (assuming you were to do this for your entire site)

Edit: to be specific the purpose is to take a key from the user and hash it before comparing it to other hashed columns in my table, then retrieve a another column value where the hashes match. Sorry for not specifying

kjh
  • 3,407
  • 8
  • 42
  • 79
  • 1
    Hash of what value compared to the hash of what value? Whole input's hash compared to what? I mean, you can't get it back because *it's a hash* – Alfabravo Jul 26 '12 at 17:28
  • Do you mean for example: select * from table where '[hash data]' = 'A';? – hmmftg Jul 26 '12 at 17:31
  • 2
    Please take a minute to understand [the difference between hashing and encryption](http://stackoverflow.com/questions/4948322/fundamental-difference-between-hashing-and-encryption-algorithms). – Tim Lehner Jul 26 '12 at 17:35

6 Answers6

9

Yes, but it'll also make your data useless. :P Remember, hashing is one-way, so you wouldn't be able to get the meaningful data back. Encryption is two way, and that's probably what you really meant.

I think using prepared SQL statements is a more widely accepted solution for this sort of thing. See this question.

Community
  • 1
  • 1
Oleksi
  • 12,947
  • 4
  • 56
  • 80
  • Never knew this either, lots of insight on this question, thanks! – kjh Jul 26 '12 at 17:50
  • @kjh Note that encryption creates binary data, which you cannot store in a traditional `char` field. This is also why I recommend using encoding (e.g.: base64) rather than encryption (e.g.: AES). – Palladium Jul 26 '12 at 17:58
3

Yes, but once you hash the information, you can't regenerate the information from the hash. Use an encoding method instead.

Also, mysql_* functions are (or soon will be) deprecated. You should consider switching to mysqli or PDO. If you're a lazy bum (like me), you can use the mysqli procedural style which is almost identical to the original mysql_ functions.

Palladium
  • 3,723
  • 4
  • 15
  • 19
  • interesting I've never even played around with msqli functions. Thanks for the tip – kjh Jul 26 '12 at 17:46
1

So long as your hashed output does not have any conflicting characters in mysql, then I would say yes, absolutely. base64 is a great approach for doing something like this

Bryan
  • 6,682
  • 2
  • 17
  • 21
1

yes but only if you store the key both encrypted and as a hash. i just finished a tcl script that does this. the major procedures should help you. take plain text key and hash, also encrypt this plain text key and store both in the same row as the form data you are saving (also encrypted).

populate a dropdown or whatever with plain text keys by decrypting the key column and inserting into the box. now you can select plain text keys to search for.

this requires an encrypt, decrypt, and hash routing that gets called every time you want to add, update, delete a record or show records but i notice no slowing though i am sure it exists at a microsecond level.

make sure your encryption comes from a standardized and respected source like openssl or similar so you can cbc with auto padding and auto IV creation. this way like words in the database are encrypted differently. this is also why you need to hash the key. otherwise it will encrypt differently and you wouldnt be able to search for anything.

in this way, a key get hashed and checked against other hashed values. try inserting a malicious group of words into a field and the wort that can happen is it gets hashed into a non-dangerous word.

if using tcl it also helps to use curly braces which should prevent problems to begin with

frodo
  • 11
  • 1
0

If you're thinking of md5() or sha1(), you'll never be able to decrypt the hash. If you have your own encryption algo, I say go for it.

Matt
  • 6,993
  • 4
  • 29
  • 50
0

In my opinion, i think you should use both of them, here is an example:

$em = mysql_real_escape_string($_REQUEST['email']);
$pw = mysql_real_escape_string($_REQUEST['password']);
at the insert you use the password($pw) function.