简体   繁体   中英

Is there a way to create a reversible opaque UUID?

Request

We need a php-only system to map a filepath/filename.ext to a UUID in a way that can be reversible.

Example

For example:

maps/shop1.jpg ->  342abfec-31fdfg-23131

The user can access this map only from

loader.php?token=342abfec-31fdfg-23131

The loader.php must be able to 'reverse' the UUID so the script can send maps/show1.jpg .

The goal

Main goal in this phase is not to secure content access.

Our goal for now is only to add an "opacity" level to avoid that an user can open for example shop2.jpg simply changing the URL.

The problem

We cannot, for now, save UUID<-->file mapping into a DB or similar.

So I've the request to create 'on the fly' the UUID corresponding to a filepath/filename.txt, and this UUID must be reversible so a PHP script can 'decode' it and serve the corresponding file.

Question

Does a reversible string to UUID algorithm already exist?

It sounds like you want it to be hard to guess URLs or spot patterns in them. The suggestion of base64 encoding in another answer is a good one, but similar inputs will still lead to similar outputs, so it may not be ideal:

maps/shop1.jpg: bWFwcy9zaG9wMS5qcGc
maps/shop2.jpg: bWFwcy9zaG9wMi5qcGc
maps/shop3.jpg: bWFwcy9zaG9wMy5qcGc
maps/shop4.jpg: bWFwcy9zaG9wNC5qcGc
maps/shop5.jpg: bWFwcy9zaG9wNS5qcGc

To avoid this, you can XOR the string with a random salt (or "nonce"), and include the salt in the URL to decode it, eg:

function base64_url_encode($input)
{
    return strtr(base64_encode($input), '+/=', '._-');
}

function base64_url_decode($input)
{
    return base64_decode(strtr($input, '._-', '+/='));
}

function obfuscate($input)
{
    $salt = random_bytes(strlen($input));
    // Make sure our separator doesn't appear in the salt, or explode() will split at the wrong place
    str_replace('|', '-', $salt);
    $xor = $input ^ $salt;
    return base64_url_encode("$salt|$xor");
}

function deobfuscate($input)
{
    [$salt, $xor] = explode('|', base64_url_decode($input), 2);
    return $salt ^ $xor;
}

Which gives strings like this:

maps/shop1.jpg: NubGQVCitxcciGC8wht8W4e2Mn_R33hsuU7Wsnw-
maps/shop2.jpg: ePr0T12ft29NwpNMslN8FZuEPHLs3wA98L0mwjQ-
maps/shop3.jpg: 7stRD6lwniLozbmY_fJ8g6ohfIYD9k2Y_pfyjZU-
maps/shop4.jpg: 1ArPov5EmGqyikHyN2l8uWu_0dE38AXCvm.YRw4-
maps/shop5.jpg: tQN2RHTzN.LCEHu1URJ82GIGN1uAX42yJVXfIXU-

(A variation of this would be to use the MD5 or SHA1 hash of the string as the salt, so that each string will always have the same obfuscated form, but still be hard to guess.)

You could even XOR a second fixed string that's not transmitted (a "key"), making this into a very simple encryption scheme. But if you want security, you're better off just using a real encryption function like sodium_crypto_secretbox .

Well what you're looking for is a an encode/decode algorithm. There's hex and base64 encodings which are usually used for the above but if you want really something unique you have to create your own.

Here's a url safe base 64 encoding/decoding example:

/**
 * Encode a string to URL Safe base 64
 */
function base64_url_encode($input)
{
    $result = strtr(base64_encode($input), '+/=', '._-');
    //remove padding
    $start = strlen($result) - 2;
    $pos = strpos($result, '-', $start);
    if ($pos !== false) {
        $result = substr_replace($result, "", $pos);
    }
    return $result;
}

/**
 * Decode a string from URL Safe base 64
 */

function base64_url_decode($input)
{
    //add back padding
    $input = str_pad($input, ceil(strlen($input)/4)*4, '-');
    return base64_decode(strtr($input, '._-', '+/='));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM