20

This is not about security. It is also not to make it hard to break. I'm looking for a simple algorithm to change a string (a url) in a way it does not resemble the original. The encryption will be done with javascript. Then I want to feed the encrypted string to a PHP function to change it back to the original. Both ends could share a secret key, or the conversions could be key-less and rely on just logic.

The ideal solution

  1. will be simple
  2. will use available javascript functions for encryption
  3. will use available php functions for decryption
  4. will produce encrypted string in way not to resemble the plain text at all
  5. will only use lower-case alphabet characters and numbers in the encrypted string
  6. is not a method widely used like Base64-ing as encryption.

Edit: The last requirement was added after shamittomar's answer.

Community
  • 1
  • 1
Majid Fouladpour
  • 29,356
  • 21
  • 76
  • 127
  • 1
    By doing this in javascript a client can easily view the source and decrypt your encrypted string. – Chris Aug 31 '10 at 12:30
  • @Chris - That would not pose a problem; as I stated in the question this is not for security or secrecy's sake. – Majid Fouladpour Aug 31 '10 at 12:36
  • this is why I posted it as a comment merely, to make sure you were aware that's all. As others have said any hashing algorithm your javascript and php have available would work just fine. md5, base64, sha will all work. – Chris Aug 31 '10 at 12:37
  • 1
    Note md5 and sha are one way hash algorithms, not applicable in this case because the OP wants to decrypt the encrypted string. – Mark Nov 15 '10 at 21:24
  • stupid question, what's the point of this? when it's not about secrecy or security and you dont want a common function for this just to weirdly encode it. I am just curious – My1 Oct 17 '17 at 09:04
  • 2
    @My1 in my country many sites are blocked. Back in the day this question was asked vpns were hard to come by and many had to rely on web proxies (themselves on http). The filtering was clever enough to reverse the base64 encoding of the target url and would block the request nevertheless. I had access to the source code of one such proxy (PHP) and wanted to change the method from base64 encoding to something different to get around this. Related: [this](https://stackoverflow.com/q/3568669/66580) and [this](https://serverfault.com/q/232872/25163). – Majid Fouladpour Oct 17 '17 at 09:40
  • well that is intresting. thanks. – My1 Oct 17 '17 at 13:28

6 Answers6

33

You can use bitwise XOR in javascript to encode the string and again in PHP to decode it again. I wrote a little Javascript example for you. It works the same in PHP. If you call enc() a second time with the already encoded string, you'll get the original string again.

<html>
<head><title></title></head>
<body>
<script type="text/javascript">
function enc(str) {
    var encoded = "";
    for (i=0; i<str.length;i++) {
        var a = str.charCodeAt(i);
        var b = a ^ 123;    // bitwise XOR with any number, e.g. 123
        encoded = encoded+String.fromCharCode(b);
    }
    return encoded;
}
var str = "hello world";
var encoded = enc(str);
alert(encoded);           // shows encoded string
alert(enc(encoded));      // shows the original string again
</script>
</body>
</html>

In PHP do something like this (caution, this is not tested and it's been a long while since I did PHP):

$encoded = "...";   // <-- encoded string from the request
$decoded = "";
for( $i = 0; $i < strlen($encoded); $i++ ) {
    $b = ord($encoded[$i]);
    $a = $b ^ 123;  // <-- must be same number used to encode the character
    $decoded .= chr($a)
}
echo $decoded;
Ridcully
  • 23,362
  • 7
  • 71
  • 86
  • 3
    +1 Thank you Ridcully, I appreciate the effort and time you put into this. – Majid Fouladpour Aug 31 '10 at 12:56
  • how does the php side work ? new to this.. but confused with it saying "It works the same in PHP". When i look up XOR it has a key too – Jason Aug 02 '12 at 12:09
  • In PHP you do exactly the same as in Javascript. First, define a variable $decoded = "". Then you iterate over the characters of the encoded string and you do a bitwise XOR with the **same** number you used at Javascript side for encoding. Thus you get the original character again. You append the decoded character to $decoded and end up with the original string. It's all based on the fact that if you apply a bitwise XOR twice, you get the original value again. – Ridcully Jun 11 '13 at 15:17
  • @crosenblum I added a PHP snippet to my answer. – Ridcully Jun 11 '13 at 15:25
  • Currently line 3 of the PHP part is obsolete?! – Möhre May 26 '15 at 09:38
  • @Möhre - Thanks, I removed the obsolete line. So for all others - there are no more obsolete lines in the php code. – Ridcully May 26 '15 at 12:05
  • very nice implementation +1 for this – Mohamed Belal Jun 14 '15 at 16:59
  • 1
    Am I the only one who has problems with this code? If I use the number 123, then all "{" disappear from my string. Every char from ascii table will disappear, if I use their number from ascii table. – Rawburner Feb 15 '17 at 15:57
  • Bitwise encoding will result a pretty nasty character set which is not necessarily in the Latin dictionary. Isn't there any issue with passing this through http and later decoding in PHP? – optimoose Mar 26 '21 at 08:20
  • can someone convert js (encode function ) into php function – Azhar Uddin Sheikh Jul 24 '21 at 19:21
13

If that's what you want, you can Base64 encode and decode that.

[EDIT]: After OP clarification:

As you do not want widely used methods, here is one rarely used method and that can do it for you by giving output only in LOWERCASE letters and NUMBERS. It is Base32 Encode/Decode. Use the following libraries:

shamittomar
  • 46,210
  • 12
  • 74
  • 78
8

If it's not about security, and not about making it hard to break, then how about ROT-13?

//+ Jonas Raoni Soares Silva
//@ http://jsfromhell.com/string/rot13 [rev. #1]

String.prototype.rot13 = function(){
    return this.replace(/[a-zA-Z]/g, function(c){
        return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);
    });
};

...

var s = "My String";

var enc = s.rot13();  // encrypted value in enc

PHP has a native function, str_rot13: http://php.net/manual/en/function.str-rot13.php

$decrypted = str_rot13($_GET['whatever']);
Fosco
  • 38,138
  • 7
  • 87
  • 101
  • 1
    But OP want to use a `URL` as input. And `Rot-13` leaves the *non-alpha characters untouched*. This may output `/` and `:` characters but OP wants output in only *lowercase and numbers*. Also, as non-alpha chars are untouched, it is very very simple to predict that the encoded string is a URL. – shamittomar Aug 31 '10 at 12:48
  • @shamittomar, there was no comment about a URL as input when this answer was made. I answered basically tongue-in-cheek based on the requirements. – Fosco Aug 31 '10 at 13:48
  • the revisions of this question show that the initial post contained following: `...to change a string (a url) in a way...`. You may have missed it :) . No problem. – shamittomar Aug 31 '10 at 13:55
4

Well I found this page and found Redcully's program not work for me so I thought It happens with all others. finally I got reason and fixed it. Here new code is... Thanks to Redcully :)

JS function:

function encode(str) {
  var encoded = "";
  for (i=0; i<str.length;i++) {
    var a = str.charCodeAt(i);
    var b = a ^ 51;    // bitwise XOR with any number, e.g. 123
    encoded = encoded+String.fromCharCode(b);
  }
  return encoded;
}

PHP function:

function decode($encoded) {
  $decoded = "";
  for( $i = 0; $i < strlen($encoded); $i++ ) {
    $b = ord($encoded[$i]);
    $a = $b ^ 51;  // <-- must be same number used to encode the character
    $decoded .= chr($a);
  }
  return $decoded;
}
Manav Akela
  • 166
  • 2
1

How are you planning to implement (hide) the secret in Javascript? IMHO it's not possible.

Edit: OK - not about security.. then just use any baseXX or rot encoding mechanism. But you can't really say one of these algorythms would not be well known...

Jan.
  • 1,925
  • 15
  • 17
  • The objective is not to hide the secret – Majid Fouladpour Aug 31 '10 at 12:33
  • @Majid whats the use of the encryption if the key is not secret? – Max Aug 31 '10 at 12:34
  • I think he means hash not encrypt. – Chris Aug 31 '10 at 12:37
  • Well.. a hash has neither to do with secret and not with encryption at all. The OP clearly states that he want to encrypt something and adds: "Then I want to feed the encrypted string to a PHP function to change it back to the original". – Jan. Aug 31 '10 at 12:40
  • @Max - It is to pass through more sophisticated filtering which decodes the proxified url to see what site is being accessed through a proxy. – Majid Fouladpour Aug 31 '10 at 13:06
0

Here is a simple (no library needed) encrypt/decrypt method to/from PHP<->Javascript.

2 responses in this topic are on the right track - but they don't work because they don't take into account how PHP handles UTF encoding. This is a fully tested/working example.

Javascript:

function _crypt(textToEncrypt) {

        var key = 128; // select any number, but make sure to match it in your PHP script
        var out = "";
        var c = "";
        for (var i = 0; i < textToEncrypt.length; i++)
        {
            c = textToEncrypt[i].charCodeAt(0) & 0xFF;
            c = (c ^ key);
            c = String.fromCodePoint(c);
            out += c;
        }
        return out;
    }

PHP:

function _crypt($textToEncrypt) {

    $key = 128;
    $out = "";
    $c = "";
    for ($i = 0; $i < mb_strlen($textToEncrypt); $i++) {
        $c = mb_ord(mb_substr($textToEncrypt, $i, 1));
        $c = ($c ^ $key);
        $c = mb_chr($c);
        $out .= $c;
    }
    return $out;
}
Kreso
  • 1
  • 2