简体   繁体   English

如何在网站URL中对内容ID号码进行Imgur式混淆? (PHP和MySQL)

[英]How to do Imgur-style obfuscation of content id number in website URL? (PHP&MySQL)

I'm trying to obfuscate the URLs to the pages where content is displayed. 我正在尝试混淆显示内容的页面的URL。 Content pages are displayed by getting the content id number as a GET variable in the URL. 通过获取内容ID号作为URL中的GET变量来显示内容页面。 I want to obfuscate the URL (as is described by this SO post ). 我想混淆URL(如本SO post所述 )。 I tried the methods in both answers but one method gave overly long codes, and the other gave overly predictable codes. 我在两个答案中都尝试了这些方法,但是一种方法给出的代码太长,而另一种给出的代码却过于可预测。

I'm working in PHP, and I'm using a MySQL table to store content; 我正在使用PHP,并且正在使用MySQL表存储内容; the content id is an automatically incrementing column. 内容ID是一个自动递增的列。 This means that if I didn't obfuscate my URLs users would be able to see in the URL exactly how many posts there are on the website, and could change the URL to see different posts. 这意味着,如果我不混淆自己的URL,用户将可以在URL中准确看到网站上有多少帖子,并且可以更改URL以查看其他帖子。 I want to avoid this. 我想避免这种情况。

I was hoping to have obfuscation similar to Imgur.com: their content ID codes are each a 5-character code containing letters, capital letters and lowercase letters. 我希望对Imgur.com感到困惑:它们的内容ID代码每个都是5个字符的代码,包含字母,大写字母和小写字母。

To avoid needing to do a bunch of "encrypting" and "decrypting" you can use a unique key-pair for each page. 为了避免进行一堆“加密”和“解密”,您可以为每个页面使用唯一的密钥对。 Add another field (VARCHAR 5) to your pages table called key and then randomly generate a key for each page. 将另一个字段(VARCHAR 5)添加到页面表中,称为key,然后为每个页面随机生成一个key。

To generate the key you could crypt a random number 要生成密钥,您可以加密一个随机数

function random_key(){
    $crypt = crypt(rand(0,9999999), 'Whatever you want to say here.');
    return substr($crypt, 0, 5);
}

Which would result in a URL like ?page=55-so3ph ( ?page={$id}-{$key} ) 这将导致像?page=55-so3ph?page={$id}-{$key} )这样的URL ?page=55-so3ph

And then to use it you can do something like 然后使用它,你可以做类似的事情

<?php

if(empty($_GET['page']))
    die('missing ?page');

$page = explode('-', $_GET['page']);

if(count($page) != 2)
    die('invalid ?page');

list($page_id, $page_key) = $page;

if(!is_numeric($page_id))
    die('invalid page id');

$Post = your_query_method('SELECT * FROM pages WHERE id = ' . $page_id . ' AND key = "' . your_escape_function($page_key) . '"');

if(!$Post){
    header('Location: /invalid_page.html');
    exit;
}

//At this point we know that they ID key pair is correct

For a super simple solution that does not really prevent people from reverse engineering your URLs but will deter 99.9999% of users you can do something like 对于一个超级简单的解决方案,它并不能真正阻止人们对您的URL进行反向工程,但可以阻止99.9999%的用户,您可以执行以下操作

<?php
function hash_id($id){
    $crypt = crypt($id, 'Whatever you want to say here. Just SALT it!');
    $md5   = md5($crypt . 'You can do another SALT here.');
    return substr($md5, 0, 5);
}

if(empty($_GET['page']))
    die('missing ?page');

$page = explode('-', $_GET['page']);

if(count($page) != 2)
    die('invalid ?page');

list($page_id, $page_key) = $page;

if(!is_numeric($page_id))
    die('invalid page id');

$Page = your_function_to_get_page_by_id($page_id);

if(!$Page || hash_id($page_id) != $page_key){
    header('Location: /invalid_page.html');
    exit;
}

//the URL would look like ?page=55-so3ph

Between crypt and md5 with salts, it would take somebody with a super computer a good chunk of time to start finding the collisions. 在带有盐的crypt和md5之间,使用超级计算机的人需要花费大量时间才能开始发现冲突。

What I've ended up doing is quite simple: I cipher the number (ensuring that the output of the cipher is within a certain range) then I convert the number to base 62. 我最终要做的事情很简单:我将数字加密(确保密码的输出在一定范围内),然后将数字转换为以62为底的数字。

I chose base 62 because the characters in base 62 are numerics, capital alphabets, and lowercase alphabets. 我选择基数62是因为基数62中的字符是数字,大写字母和小写字母。 I ensured the output of the cipher was within a certain range so that when converted to base 62 it would have a certain number of digits (in my case I chose six digits in base 62). 我确保密码的输出在一定范围内,这样当转换为基数62时它将有一定数量的位数(在我的情况下,我在基数62中选择了六位数)。

To reverse the code, I convert it back to base 10 and reverse the cipher. 为了反转代码,我将其转换回以10为基数并反转密码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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