?
Solved

$queryString encrypt

Posted on 2012-08-20
20
Medium Priority
?
655 Views
Last Modified: 2012-08-29
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
0
Comment
Question by:rgb192
  • 6
  • 6
  • 5
  • +1
20 Comments
 
LVL 60

Expert Comment

by:Julian Hansen
ID: 38315181
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
 

Author Comment

by:rgb192
ID: 38315236
>>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
 
LVL 60

Expert Comment

by:Julian Hansen
ID: 38315314
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
Nothing ever in the clear!

This technical paper will help you implement VMware’s VM encryption as well as implement Veeam encryption which together will achieve the nothing ever in the clear goal. If a bad guy steals VMs, backups or traffic they get nothing.

 
LVL 36

Expert Comment

by:Loganathan Natarajan
ID: 38315416
Otherwise, you can convert the ID to SEO enabled way of URL's.. you could use some keyword titles
0
 
LVL 36

Expert Comment

by:Loganathan Natarajan
ID: 38315418
0
 
LVL 36

Expert Comment

by:Loganathan Natarajan
ID: 38315423
0
 
LVL 35

Accepted Solution

by:
gr8gonzo earned 2000 total points
ID: 38315741
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
 
LVL 35

Expert Comment

by:gr8gonzo
ID: 38315764
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
 

Author Comment

by:rgb192
ID: 38317208
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
 
LVL 35

Expert Comment

by:gr8gonzo
ID: 38317279
Just leave off the urlencode("==") part or change the check to:

$keyShouldBe = "az09".md5("!rgb192".$id).("==");
0
 

Author Comment

by:rgb192
ID: 38318822
>>
$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
 
LVL 35

Expert Comment

by:gr8gonzo
ID: 38318900
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
 
LVL 60

Expert Comment

by:Julian Hansen
ID: 38319392
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
 

Author Comment

by:rgb192
ID: 38319503
>>
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
 
LVL 60

Expert Comment

by:Julian Hansen
ID: 38319852
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
 
LVL 35

Expert Comment

by:gr8gonzo
ID: 38319911
> 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
 
LVL 35

Expert Comment

by:gr8gonzo
ID: 38319962
@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
 
LVL 60

Expert Comment

by:Julian Hansen
ID: 38319967
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
 

Author Closing Comment

by:rgb192
ID: 38330072
best answer,
works for me
0
 

Author Comment

by:rgb192
ID: 38346894
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

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This post contains step-by-step instructions for setting up alerting in Percona Monitoring and Management (PMM) using Grafana.
This post looks at MongoDB and MySQL, and covers high-level MongoDB strengths, weaknesses, features, and uses from the perspective of an SQL user.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to dynamically set the form action using jQuery.
Suggested Courses
Course of the Month13 days, 18 hours left to enroll

807 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question