skip to Main Content

I’m working on a quote generating system that creates a quote for a user and saves it to a database. I’d like users to be able to share their quotes with friends and family without exposing the auto-incrementing ID (to avoid revealing the number of generated quotes).

I’ve created the following two functions to encode and decode the ID for sharing purposes:

function encode_id($id, $secret_key) {
    if (!is_numeric($id)) {
        return false;
    }else{
        return $id ^ $secret_key;
    }
}


function decode_id($encoded_id, $secret_key) {
    if (!is_numeric($encoded_id)) {
        return false;
    }else{
        return $encoded_id ^ $secret_key;
    }
}

However, these functions don’t provide enough randomness and still exhibit a pattern. Are there any best practices or recommendations for implementing a more secure and concise solution, similar to a UUID or uniqid but not as lengthy?

2

Answers


  1. Chosen as BEST ANSWER

    I ended up going with Hashids with a custom library. Pleased with it.


  2. This is a bidirectional encryption method.

    function encode_id($id, $secret_key) {
    
    
            $key = $secret_key;
            $plaintext = $id;
            $ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
            $iv = openssl_random_pseudo_bytes($ivlen);
            $ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
            $hmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
            $ciphertext = base64_encode( $iv.$hmac.$ciphertext_raw );
    
            return $ciphertext;
    }
    
    
    function decode_id($ciphertext, $secret_key) {
    
        $key = $secret_key;
        $c = base64_decode($ciphertext);
        $ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
        $iv = substr($c, 0, $ivlen);
        $hmac = substr($c, $ivlen, $sha2len=32);
        $ciphertext_raw = substr($c, $ivlen+$sha2len);
        $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
        $calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
    
        return $original_plaintext;
    }
    

    Example :

    $text_coded = encode_id(3,3);
    
    echo $text_coded; // JzRQHpTKMKkrMUgBdRsA8WQzJiSdjKVD4E9lXNWhC6CiIrGc1bKNcScpK1AHVIYHRyTjEL48i/2xPOhJpmA1Rw==
    
    echo "<br><br>";
    
    echo decode_id($text_coded,3); // 3
    

    Try it and tell me if you found it useful

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search