$queryString encrypt

I am using php query strings
which are sequental integers
queryString=1
queryString=2
queryString=3


so 1 bad user can create many query string urls in a browser,


so I will use crypt($queryString,$salt)

my problems are
1. I cant decrypt to add to database

2. when encrypted $queryString is in database, I want to left join with another table which has the decrypted value
LVL 1
rgb192Asked:
Who is Participating?
 
gr8gonzoConsultantCommented:
rgb192 - Don't encrypt the values. Just use a custom checksum or key to prevent a bad user from changing the IDs. For example, if the URL is:

http://www.server.com/queryscript.php?ID=13

...then a malicious user can change 13 to 14 and see other data. However, if you have a checksum or key like this:

http://www.server.com/queryscript.php?ID=13&key=az09df01d990afe9216000376542==

...and if that "abdf01..." key belongs to ID=13 only, then a malicious user cannot change ID to 14 and get a result. Here is a simple way to do it. When you generate your URLs, create the key like this:

$id = 13;
$key = "az09".md5("!rgb192".$id).urlencode("==");
$url = "http://www.server.com/queryscript.php?ID=$id&key=$key";
echo $url;

Then, when someone clicks on one of those links, you simply verify that same key:

$id = intval($_GET["id"]);
$key = $_GET["key"];
$keyShouldBe = "az09".md5("!rgb192".$id).urlencode("==");
if($key != $keyShouldBe)
{
    // The special key doesn't match, so it's probably some malicious user trying to break in.

    sleep(5); // Slow the user down.
    die(); // Stop the script completely from continuing.
}

... rest of your code as normal ...
0
 
Julian HansenCommented:
Crypt is a one way function so you cannot decrypt it

You can have a look here for samples

http://stackoverflow.com/questions/1289061/best-way-to-use-php-to-encrypt-and-decrypt

2. To join to second table - you will need to look at the encryption / decryption functions of your database if MySql you can get more info here

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

The question though is why do you want to encrypt the values if you are going to have them unencrypted in another table.
0
 
rgb192Author Commented:
>>http://dev.mysql.com/doc//refman/5.5/en/encryption-functions.html
I cant find how to join tables if one value is encrypted

>>The question though is why do you want to encrypt the values if you are going to have them unencrypted in another table.

a user can visit all the query strings if the numbers are in order
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

 
Julian HansenCommented:
a user can visit all the query strings if the numbers are in order

I don't understand this - maybe describe in a bit more detail what you want to do - there may be an easier way than what you are trying to do.
0
 
Loganathan NatarajanLAMP DeveloperCommented:
Otherwise, you can convert the ID to SEO enabled way of URL's.. you could use some keyword titles
0
 
Loganathan NatarajanLAMP DeveloperCommented:
0
 
Loganathan NatarajanLAMP DeveloperCommented:
0
 
gr8gonzoConsultantCommented:
To explain my suggestion a little more, the idea is to come up with some kind of value that REPRESENTS the original ID. You could even just do:

$key = md5($id);

...but if a hacker is determined, he or she might try to guess that that is the special formula to make the key. By adding little bits of custom text into it, you are creating your own formula. A hacker will not know what az09 stands for, they will know know that you are modifying the hash value with "!rgb192" and they are not going to guess that the ending "==" do not have any value by themselves. In fact, the == at the end can throw hackers off and make them believe that the value is a Base64-encoded value.

So you use this formula to create a special key that will be unique to your ID, but it can be generated the same way every time as long as you know the formula (which your scripts will know, but hackers will not).

Since the key changes when the ID changes, you will always have a different key for each ID, and people who follow the links normally will be able to access everything the same way they always have, while hackers will not be able to recreate the key easily. And you don't have to change any database queries.
0
 
rgb192Author Commented:
do all base64-encoded values have
%3D%3D
==

at the end of the url

could there be different characters


<?php
echo '<table>';
for ($id = 13;$id<40;$id++){



$key = "az09".md5("!rgb192".$id).urlencode("==");
$url = "http://www.server.com/queryscript.php?ID=$id&key=$key";
echo '<tr><td>'.$id.'</td><td>'.$url.'</td></tr>';
}






$id = intval($_GET["id"]);
$key = $_GET["key"];
$keyShouldBe = "az09".md5("!rgb192".$id).urlencode("==");
echo '<tr><td></td><td></td></tr>';
echo '<tr><td>'.$id.'</td><td>'.$key.'</td><td>'.$keyShouldBe.'</td></tr>';

echo '</table>';

if($key != $keyShouldBe)
{
    // The special key doesn't match, so it's probably some malicious user trying to break in. 
   echo '<br>error';
    //sleep(5); // Slow the user down.
    //die(); // Stop the script completely from continuing.
}else{
  echo '<br>works';
}

Open in new window




this is the output when I copypaste the url from id=39 into the url

== will never be the same as %3D%3D


13 http://www.server.com/queryscript.php?ID=13&key=az09ac56d960f745c6890b8f92693246e5e9%3D%3D 
14 http://www.server.com/queryscript.php?ID=14&key=az09c81be36d5fa339a2fe37c41504dc3bed%3D%3D 
15 http://www.server.com/queryscript.php?ID=15&key=az09f3a0f5654c18e292b43660377cf3d224%3D%3D 
16 http://www.server.com/queryscript.php?ID=16&key=az090dce836b0b700658255c3a4caaf75d80%3D%3D 
17 http://www.server.com/queryscript.php?ID=17&key=az09d980ece962d81104d238922e08e54589%3D%3D 
18 http://www.server.com/queryscript.php?ID=18&key=az09048d647c7e2b2808210eaeac5382b810%3D%3D 
19 http://www.server.com/queryscript.php?ID=19&key=az090236af4801a319c4fce5c317d49b7248%3D%3D 
20 http://www.server.com/queryscript.php?ID=20&key=az09ad8e29b75eeae73122be9679285133b7%3D%3D 
21 http://www.server.com/queryscript.php?ID=21&key=az09754126edd8a7f194e77606db44e2e567%3D%3D 
22 http://www.server.com/queryscript.php?ID=22&key=az09347189491655dcd95e5e982517d88049%3D%3D 
23 http://www.server.com/queryscript.php?ID=23&key=az0909f8d1bae26b1405706fdca05fa9ce57%3D%3D 
24 http://www.server.com/queryscript.php?ID=24&key=az090415bc67af0d7e8ddc3052737eb96f09%3D%3D 
25 http://www.server.com/queryscript.php?ID=25&key=az095a430eed86e61283be72491b35e32472%3D%3D 
26 http://www.server.com/queryscript.php?ID=26&key=az0914f8b07bb0f513b969d3ca4a562bfa45%3D%3D 
27 http://www.server.com/queryscript.php?ID=27&key=az0997b12232b76f46f39930c89220aacd51%3D%3D 
28 http://www.server.com/queryscript.php?ID=28&key=az0963005592284133c505cda36eb91011ef%3D%3D 
29 http://www.server.com/queryscript.php?ID=29&key=az0904ce9dc597ee2d834010b3883ce4e18c%3D%3D 
30 http://www.server.com/queryscript.php?ID=30&key=az099f732fbf992868f833d350d448cf382e%3D%3D 
31 http://www.server.com/queryscript.php?ID=31&key=az098da980b048cbbf79916b369c5f31b1e4%3D%3D 
32 http://www.server.com/queryscript.php?ID=32&key=az09ff4ded8e5711e7f81159036b18460fb4%3D%3D 
33 http://www.server.com/queryscript.php?ID=33&key=az091490bfcef744e55c44d19a263b23b459%3D%3D 
34 http://www.server.com/queryscript.php?ID=34&key=az098b883bffe9d57a075e2618a4db4a06d9%3D%3D 
35 http://www.server.com/queryscript.php?ID=35&key=az0931bf5a5f550e2abc6e97e16fc84ce933%3D%3D 
36 http://www.server.com/queryscript.php?ID=36&key=az09b1ca153a33334a87bab896062a85a54d%3D%3D 
37 http://www.server.com/queryscript.php?ID=37&key=az09cd5d6b5ef08c74f42e85b2b9adb7c578%3D%3D 
38 http://www.server.com/queryscript.php?ID=38&key=az091c564c29c3843d7d2a9ae64d07953288%3D%3D 
39 http://www.server.com/queryscript.php?ID=39&key=az0920c0f31ee3363835971baeab0c8dc0fa%3D%3D 
 
39 az0920c0f31ee3363835971baeab0c8dc0fa== az0920c0f31ee3363835971baeab0c8dc0fa%3D%3D

error
0
 
gr8gonzoConsultantCommented:
Just leave off the urlencode("==") part or change the check to:

$keyShouldBe = "az09".md5("!rgb192".$id).("==");
0
 
rgb192Author Commented:
>>
$keyShouldBe = "az09".md5("!rgb192".$id).("==");
works






do all base64-encoded values have
%3D%3D
==

at the end of the url

could there be different characters
0
 
gr8gonzoConsultantCommented:
They don't always end with == but they often end with one or two = signs so its good to throw them in to mislead hackers
0
 
Julian HansenCommented:
The problem with this approach is you have to maintain a list of keys to lookup to see what the actual key is.

Unless security is of paramount importance you can achieve the same result with a two way function and secret key so
<?php
define('confuscator', 109287);

function extract_key($key)
{
  $temp = $key / confuscator;
  return sqrt($temp);
}

function make_key($id)
{
  return $id * $id * confuscator;
}

for($i=0;$i<100;$i++) {
  $key = make_key($i);
  echo "Key $i : " . $key . " : Decrypted " . extract_key($key) . "<br/>"; 
}
?>

Open in new window

0
 
rgb192Author Commented:
>>
The problem with this approach is you have to maintain a list of keys to lookup to see what the actual key is.

I dont understand about the list

I thought it was 1 salt
0
 
Julian HansenCommented:
Not sure what your question is - to explain my post further.

If I understand your requirement you want a way to hide the id value so that visitors cannot guess other values and therefore go to other pages they shouldn't have access to.

The solutions posted above make use of a 1 way hash i.e. you can easily convert from your id to the url key using something like md5 and a salt to obfiscate the results but when you get that URL coming back to your application you still need to translate the key back into an id you can use to deliver the page.

The solution I posted was given as an alternative that allows you to create a key from your id that does not follow a semmingly logical sequence and so subsequent page id's cannot be easily guessed but you can reverse the process to extract the actual id.

So in otherwords you can have a url that would normally be this

http://www.mysite.com/index.php?id=1

So user can guess

http://www.mysite.com/index.php?id=1
http://www.mysite.com/index.php?id=2
http://www.mysite.com/index.php?id=3

What you want is this

http://www.mysite.com/index.php?id=109287
http://www.mysite.com/index.php?id=437148
http://www.mysite.com/index.php?id=983583

If you run the script I posted you will see the above values are what is output for id = 1, 2 and 3 - you can also see from the above that there is no logical progression between the numbers.

The main thing is the process is reversible - so you can take 109287 divided it by the confuscator value and take the square root to get the actual page id - so the number is reversible. If you get an answer outside of your id range or that is not an int you know the request is invalid. So if someone tries to enter

http://www.mysite.com/index.php?id=109288

The id returned will be 1.0000018300371314656548983253766 which is not an int so is invalid.

The solution can be further enhanced by adding a checksum (sum of all digits until only a single digit remains) which is appended or prepended to the string which can act as a further check for validity.

There are many things you can do to further obscure the numbers (adding / subtracting / multiplying by constants) but this was meant to demonstrate the simplest version of this.

The script above will output the following for i=1 to 10. This output shows
a) The obscured value which you use in your url
b) The value after it has been through the decrypt process.
Key 1 : 109287 : Decrypted 1
Key 2 : 437148 : Decrypted 2
Key 3 : 983583 : Decrypted 3
Key 4 : 1748592 : Decrypted 4
Key 5 : 2732175 : Decrypted 5
Key 6 : 3934332 : Decrypted 6
Key 7 : 5355063 : Decrypted 7
Key 8 : 6994368 : Decrypted 8
Key 9 : 8852247 : Decrypted 9
Key 10 : 10928700 : Decrypted 10

Open in new window

There is always the option of using the crypt functions as well but I feel those are overly complex for what is required. The above is quick and simple and will deter all but the most determined user from guessing your URL's.
Also if there is no requirement for your URL's to be cached you can change the confuscator value at regular intervals and have completely different url's for the same page without any changes to your application logic.
(Not a good idea if these pages are significant for an SEO strategy though).
0
 
gr8gonzoConsultantCommented:
> The problem with this approach is you have to maintain a list of keys to lookup to see what the actual key is.

JulianH, that is incorrect. There is no list of keys to maintain. The key/check is generated on-demand - once when the URL is created and once when someone clicks on the link and we want to validate the ID. The key is not used for any lookups - it is simply a signature that is validated to help ensure that someone has not tampered with the ID.

Look closer at the URL that is being generated:

http://www.server.com/queryscript.php?ID=13&key=az09ac56d960f745c6890b8f92693246e5e9%3D%3D 

it has the original ID value AND the key. The key is just an anti-tamper mechanism, but that is all. The original ID is still there and is the value that is used in the lookups and queries.
0
 
gr8gonzoConsultantCommented:
@julianh - On a separate note, I would advise against using the squaring strategy for precisely the reason that you mentioned yourself - it is limited in the number of records you can use. You cannot have even 150 records before that approach fails. You can reduce the confuscator to increase range (up to a maximum of 32k records with a confuscator of 2) , but you're imposing an unnecessary limit and you're breaking the first rule of cryptography: "Don't roll your own."

If you're going to do any kind of two-way crypto, use a tried-and-true library to do it, and Base64-encode the results if you need to pass the encrypted data in a URL.

@rgb192 - there's no reason to use two-way / reversible algorithms here.
0
 
Julian HansenCommented:
Ah ok - gotcha - however the benefits of my proposed solution remain in that your url only contains one marginally simpler value which does not give a clear idea of how it is used.

I offer it as an alternative
0
 
rgb192Author Commented:
best answer,
works for me
0
 
rgb192Author Commented:
I have a similar question

if $id gets large, encryption does not work

http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_27846884.html
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.