2

I'm looking from some kind of obfuscation bidirectional algorithm, that maps integer (in a range, like [0 , 2^10]) to a string, to avoid URL manipulation

I see here that is suggested to generate a random string and use that as ID, but I need to associate this string to already existing data, thing that I would not consider that scalable, since I would have to generate the string for 400k entries... and furthermore, I can't encrypt it since I need this to be stored in a NFC tag, and so the memory is very limited

For the moment, I'm converting int to UUID, but at the end of the day, this changes anything, it's just the int value with some 0s as paddings

Are there anything like this?

The use cause would be:

mywebsite.com/something/1
# becomes
mywebsite.com/something/{string n char long}

where I can convert that string to int and the other way around, so there is no "easy way" for someone to go to mywebsite.com/something/2

I just need an idea, but if someone has already something like this in PHP, thank you

Alberto Sinigaglia
  • 12,097
  • 2
  • 20
  • 48
  • Do you have some example "`string n char long`" for us? Or should it just work with any and all characters? After all characters are just numbers too, so you could convert it to base-10 numbers. Also, what are you doing that for? If the aim is to have a secure link, DON'T just use obfuscation. It is likely not secure enough. – ArSeN Sep 23 '21 at 20:20
  • @ArSeN I mean, 256byte should be the whole URL, but I mean, 16 letters, with an alphabeth of 26 chars, is more than enough combinations to be very sparse the matches (btw, I'm not using this as security, this url is public to all the people that needs this.... but I would like to avoid stupid brute force to happen) – Alberto Sinigaglia Sep 23 '21 at 20:57
  • Why not go with a hash of the value + a secret as a token? `mywebsite.com/something/1/{sha512('1'.'secret')}` You can then easily take the `1` from that URL and calculate `sha512('1'.'secret')` on the receiving end again, and see if it matches the token value from the URL. Sure, anyone can still guess the `2` for the next item - but they won't be able to calculate the corresponding token, because they don't know your `secret`. – CBroe Sep 24 '21 at 07:19
  • @CBroe however, how do you get back the ID form that token? hashing is unidirectional – Alberto Sinigaglia Sep 24 '21 at 09:30
  • Id is still in the URL: `/something/1/hash_here` I didn't _replace_ the ID with the token, I _added_ the token. – CBroe Sep 24 '21 at 09:34
  • @CBroe well you are right, it's actually not a bad idea imo, thanks for sharing – Alberto Sinigaglia Sep 24 '21 at 12:17

1 Answers1

2

As mentioned in comments, obscurity is not security. But, here is an idea that is easily reversable:

Convert to base 36 (or maybe base 35 to be less predictable)

function obfuscate(int $id) : ?string
{
    return $id
      ? strtolower(str_pad(base_convert($id, 10, 36),4,'0', STR_PAD_LEFT))
      : null;
}

function unobfuscate(?string $code) : ?int
{
    return $code
      ? base_convert($code, 36, 10)
      : null;
}


$numbers = [0,1,2,3,4,200,400,560,1000,1234567];
$obscure = [];
foreach($numbers as $number) {
    $obscure[] =  obfuscate($number);
    print obfuscate($number) . "\n";
}

foreach($obscure as $code) {
    print unobfuscate($code) . "\n";
}

// yields:
0001
0002
0003
0004
005k
00b4
00fk
00rs
qglj

1
2
3
4
200
400
560
1000
1234567

To obfuscate it more, you could add random decoy letters/numbers to the beginning or end. (I'll let you work out the details on that)

Beware though, you could end up with some urls that are not family-friendly ;)

working sample here: http://sandbox.onlinephpfunctions.com/code/d16a81c9e07c5e26ed4045d6363bbe41763470f0

I couldn't resist... 26 character working sample here: http://sandbox.onlinephpfunctions.com/code/61c919b7e294fa96377f2fe0edddb874a9a4b9ba

Tim Morton
  • 2,614
  • 1
  • 15
  • 23
  • thank you so much, you have done more than what I deserve (even though 1 is still 1, 2 is still 2 and so on... however, I think I'm going is HASHIDs) – Alberto Sinigaglia Sep 24 '21 at 00:44
  • true, if you’re looking for 0001 etc, it can stick out. but if it’s buried in the middle of the url, then maybe not so much. Either way, it’s just obfuscation. Enjoy! – Tim Morton Sep 24 '21 at 00:50