What's a simple symmetric way to encrypt a string and pass through a url in php?

1.7k views Asked by At

As the question states, I need a way to encrypt a string (i.e. 'x=27&y=3&z=123456' into 'hUIgBG5664y65H2UIB') so that it can be passed via an html image source, like so:

<img src="returnpicture.php?stuff=hUIgBG5664y65H2UIB"/>

returnpicture.php will decrypt that back into 'x=27&y=3&z=123456' and parse it into three variables which will be used to pick an image and return it.

Problem is, everywhere I look, all I can find is stuff about hashing and encrypting super-sensitive information like credit cards and passwords. This info is not sensitive at all, I just don't want users to be able to tamper with it. Therefore, it shouldn't be excessively long. Also, the encryption (I'm guessing) must be alphanumeric, so as not to mess up the url with & or =. I'm doing this in php.

It's for a sort of game. The user shouldn't be able to mess with the variables, 'cause they'll see things they shouldn't yet.

3

There are 3 answers

3
SQRCAT On BEST ANSWER

For general understanding

When you include certain key-value pairs in your request url, PHP will load these values (accordingly) into the $_GET superglobal.

?x=12&y=13

Will result in

$_GET['x'] // contains 12
$_GET['y'] // contains 13

What you seem to be trying to do is to supply multiple key-value pairs within a key-value pair:

?stuff={more-key-value-pairs}

Simply be aware that PHP will not interpret key-value pairs in $_GET['stuff'].

Encoding/Decoding

Note: This is one possible solution out of many. Find the one that suits you most and apply it.

You can use base64_encode() to encode it, and base64_decode() to decode it.

Example:

echo '<img src="returnpicture.php?stuff=' . rawurlencode( base64_encode('x=27&y=3&z=123456') ) . '" />';  

Usage of rawurlencode() assures proper url safe encoding of the base64-encoded string.

In your returnpicture.php you can use:

$decodedString = base64_decode( $_GET['stuff'] );

to get back your original string.

However, if you actually plan on sending a get-request like string (with variable assignments, such as ?x=12&y=13 and so on, then you need to apply further techniques to get that string parsed.

See this question for details on how it can be done

1
Ignacio Ocampo On

I suggest that you can share information between your pages with $_SESSION vars, but, it only works if two pages are in same context server.

Approach 1. base64 encode

<img src="returnpicture.php?stuff=<?php echo base64_encode('x=27&y=3&z=123456'); ?>"/>

And get this as:

$data = base64_decode($_GET['stuff']);

Approach 2. $_SESSION variables

You should combine $_GET with $_POST without expose sensible information like:

$postfix = uniqid(); // Generate an UNIQUE id
$_SESSION['sensible_var1_'.$postfix] = "value";
$_SESSION['sensible_var2_'.$postfix] = "value";
$_SESSION['sensible_var3_'.$postfix] = "value";

And you can pass this information only with:

<img src="returnpicture.php?stuff=<?php echo $postfix; ?>"/>

And in your returnpicture.php file, you can retrive information as:

$sensible_var1 = $_SESSION['sensible_var1_'.$_GET['stuff']];
$sensible_var2 = $_SESSION['sensible_var2_'.$_GET['stuff']];
$sensible_var3 = $_SESSION['sensible_var3_'.$_GET['stuff']];
0
Dagg Nabbit On

You could use a simple cipher, like a rolling XOR hash. This is very easy to implement, but enough of a nuisance to crack that people probably won't bother if the only benefit is something trivial, like the ability to get your server to serve images in non-standard sizes.

function scramble(key, text) {
    return encodeURIComponent(text.replace(/[^\0]/g, function(x, i) {
        var code = x.charCodeAt(0) ^ key.charCodeAt(i % key.length);
        return String.fromCharCode(code);
    }));
}

function descramble(key, text) {
    return decodeURIComponent(text).replace(/[^\0]/g, function(x, i) {
        var code = x.charCodeAt(0) ^ key.charCodeAt(i % key.length);
        return String.fromCharCode(code);
    });
}

If your key is "secretcode" and your text is "x=27&y=3&z=123456", then scramble(key, text) returns "%0BXQEC%0D%5E%5CB%1FNTQAQAU".

"Descrambling" that result with the same key gives the original text, "x=27&y=3&z=123456".

Note that you'd probably want to do this on the PHP side of things, the JavaScript code is just here as an example.

http://jsfiddle.net/m92rc/