11

I intend to use GET for my form but would like to encrypt the values in the query string so that users are not able to change it. (not for security, but for data hiding purposes)

I came across a couple of websites which explained encryption, but it is not clear to me how to implement it once the user presses the submit button. Ex: http://myscriptlibrary.wordpress.com/2010/04/14/how-to-encrypt-query-string-in-php/

Is there an example which could show this?

Thanks.

SEU
  • 1,304
  • 4
  • 15
  • 36

4 Answers4

25

From my understanding of the link that you provided. You want to encrypt the GET variables, or at least obfuscate them.

The best and easiest way that this could be done is using base64_decode/encode For example to encode the string you would do something like:

$link = "http://www.example.com/?item=".urlencode(base64_encode("user-data"));

$link would look something like http://www.example.com/?item=rklgEwkelnf%3D%3D, but to translate the seemingly garbled (base64ed) text into something usable you would use:

foreach($_GET as $loc=>$item)
    $_GET[$loc] = base64_decode(urldecode($item));

Then you can freely use the $_GET variable as you normally would.

D. Ataro
  • 1,711
  • 17
  • 38
Glenn Dayton
  • 1,410
  • 2
  • 20
  • 38
  • 1
    Hi, Thanks for your response. I do understand this part of using urlencode/decode. However, my issue is, how do I change the "action" script which is invoked when SUBMIT is pressed. Typically a form would like like the one below. How do I change this "form_action.php" to "form_action.php?fname=encryptedVal&lname=encryptedVal2" ?
    First name:
    Last name:
    `
    – SEU Aug 24 '12 at 08:21
  • That would have to be done via javascript. I'll try to mockup a solution. – Glenn Dayton Aug 24 '12 at 17:24
  • Here is a stackoverflow link on how to base64 encode in javascript: [stackoverflow](http://stackoverflow.com/questions/246801/how-can-you-encode-to-base64-using-javascript), all you would need to do is encode the string for the request to the server. And then let the PHP handle the rest. – Glenn Dayton Aug 24 '12 at 17:28
11

The following solution is easy enough to implement and is strong enough unless you deal with very sensitive data such as credit-cards information or NASA algorithms...

When you send the parameter via. GET - add a hash value along with it, for example:

$parameter = "abc"; //The parameter which you'll pass as a GET parameter
$salt = "cV0puOlx";
$hashed = md5($salt.$parameter);//A hash that you'll pass as well
header("Location: http://www.yourdomain.com?param=$parameter&hash=$hash");

Then when you read the parameters, check that the hash is a valid one:

$parameter  = $_GET['param'];
$hash = $_GET['hash'];
$salt = "cV0puOlx";
$hashed = md5($salt.$parameter);
//now you check:
if ($hash === $hashed){
   //everything's fine - continue processing
}
else{
  // ERROR - the user tried to tamper with your parameter
  // show error-message and bail-out
}
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
10

1- Crypt your var

2- Make sure to encode correctly with base64 MIME.

3- Do what you want (example : store in your database in order to decrypt later, pass into GET etc ...)

4- Decode base64 safely your var.

5- Decrypt your var

I implemented a class which does the job. (security and data hiding) Use openssl method with aes-256 mode cbc to secure crypt (don't forget initialization vector)

class Encryption{

    public static function safe_b64encode($string='') {
        $data = base64_encode($string);
        $data = str_replace(['+','/','='],['-','_',''],$data);
        return $data;
    }

    public static function safe_b64decode($string='') {
        $data = str_replace(['-','_'],['+','/'],$string);
        $mod4 = strlen($data) % 4;
        if ($mod4) {
            $data .= substr('====', $mod4);
        }
        return base64_decode($data);
    }

    public static function encode($value=false){ 
        if(!$value) return false;
        $iv_size = openssl_cipher_iv_length('aes-256-cbc');
        $iv = openssl_random_pseudo_bytes($iv_size);
        $crypttext = openssl_encrypt($value, 'aes-256-cbc', 'your security cipherSeed', OPENSSL_RAW_DATA, $iv);
        return self::safe_b64encode($iv.$crypttext); 
    }

    public static function decode($value=false){
        if(!$value) return false;
        $crypttext = self::safe_b64decode($value);
        $iv_size = openssl_cipher_iv_length('aes-256-cbc');
        $iv = substr($crypttext, 0, $iv_size);
        $crypttext = substr($crypttext, $iv_size);
        if(!$crypttext) return false;
        $decrypttext = openssl_decrypt($crypttext, 'aes-256-cbc', 'your security cipherSeed', OPENSSL_RAW_DATA, $iv);
        return rtrim($decrypttext);
    }
}

Example :

$pass_get = 'hello';
$base64_crypt = Encryption::encode($pass_get); // get base64 of crypt data

// Later pass into $_GET for example

<a href="https://toto.com?v=<?php echo $base64_crypt;?>" >Other page</a>

// In your other page, recover your var

$my_get_crypt_var = $_GET['v'];
Encryption::decode($my_get_crypt_var); // return 'hello' or false in case the string to be decrypted is invalid.

!!! This solution is not hashing, but CRYPTING ! So, it means that you can recover the content of your var. Can be used for no sensitive data, but not for password for example. !!!

Louis Schwartz
  • 162
  • 2
  • 6
7

The accepted answer here doesn't provide any real protection. You can just take the encoded parameters and put them into an online base64_decode and it shows the values as if you have just passed them directly!

The other answer uses $hash as a pass through value but that value hasn't been defined only $hashed.

HeavyHead
  • 310
  • 3
  • 11