2008-11-29 51 views
7

我正在構建一個帶源系統,我在'提供可採用的虛擬寵物的網絡上發佈。該系統將主要由孩子擁有。由於我希望它可以用於絕對的初學者程序員,因此我的系統中存在一些複雜性約束:它不能使用通常不隨PHP提供的庫,也不能訪問數據庫或寫入其他永久存儲。在PHP中簡單加密

當每隻寵物被採納時,訪問者會隨機獲得該寵物的一系列略有不同的變化之一。變化最初看起來是一樣的,但隨着時間的推移成長成爲不同的寵物。訪問者將被給予HTML鏈接到他們的寵物圖像短代碼。由於服務器端沒有永久性存儲器,因此用戶的圖像鏈接必須包含所有信息以確定它們最終得到的寵物差異。

目前,URL只包含寵物的ID和用戶獲得的變體的ID。與此相關的問題是,通過比較代碼,用戶可以計算出他們中的哪些人得到相同的變化。由於某些變化比其他變化更爲罕見,因此用戶可以輕鬆地發現罕見的變化,甚至在差異甚至在視覺上變得明顯。

我想要的是一個加密系統的URL中的細節。某些隱藏變體ID的內容,以便每個用戶都可能獲得不同的URL。我想過使用變化ID(3或4位)作爲一個大的隨機數的低位或高位,但用戶會發現這種模式。理想情況下,加密系統將被參數化,以便我的系統的每次安裝都會使用稍微不同的加密。

PHP的mcrypt庫可能會有一些有用的東西,但它似乎不是很常見的主機之間。

是否有一個簡單的,參數化的,混淆/加密我可以在這裏使用?

回答

9

如果您期望複雜程度相對較低,那麼您可以做一個非常簡單的「xor」加密,並將該「密鑰」存儲爲URL的一部分。然後你可以使用php的rand()或/ dev/random或其他來產生密鑰。

低技術含量的用戶不會輕易地發現,他們需要做的只是將寵物ID的下半部分與上半部分進行比較,以獲得可以與朋友比較的價值。我猜想大多數人能夠認識到發生的事情並不需要花時間來解決問題,而且這些人無論如何都不在目標羣體中。

編輯:如果它不明顯,我說你給每個寵物一個不同的關鍵(因爲給同一個不會解決你的問題)。所以如果寵物變異(petvar)是一個16位的數字,你會生成一個16位的隨機數(rnd),那麼你可以這樣做:petvar = (petvar^rnd)<<16 | rnd;,然後你可以反轉該操作來提取rnd,然後petvar^rnd,然後只需再次得到原始petvar。

+0

聽起來像一個很好的策略。我也可以使用特定於安裝的密鑰對整個字符串進行異或。你對「攻擊者」的複雜程度的直覺是非常正確的.. :) – thenickdude 2008-11-29 03:30:55

2

爲什麼不給每個用戶一個長的隨機ID,然後在服務器上存儲關於他們寵物的所有細節?最佳做法是不要在URL中存儲任何內容,並且不加密。所有你需要的是一個會話ID。

+0

當然,這就是我在我自己的服務器上所做的。但是我想要一個系統,即使沒有像樣的存儲空間,孩子們可以在自己的服務器上使用系統來贈送寵物:數據庫並不總是在免費提供商上提供,並且很難配置,平面文件存儲需要太多的代碼。 – thenickdude 2008-11-29 04:55:55

16

您正在尋找「一次性填充」加密。它需要一個密鑰併爲字符創建模數以創建加密字符串。

function ecrypt($str){ 
    $key = "abc123 as long as you want bla bla bla"; 
    for($i=0; $i<strlen($str); $i++) { 
    $char = substr($str, $i, 1); 
    $keychar = substr($key, ($i % strlen($key))-1, 1); 
    $char = chr(ord($char)+ord($keychar)); 
    $result.=$char; 
    } 
    return urlencode(base64_encode($result)); 
} 


function decrypt($str){ 
    $str = base64_decode(urldecode($str)); 
    $result = ''; 
    $key = "must be same key as in encrypt"; 
    for($i=0; $i<strlen($str); $i++) { 
    $char = substr($str, $i, 1); 
    $keychar = substr($key, ($i % strlen($key))-1, 1); 
    $char = chr(ord($char)-ord($keychar)); 
    $result.=$char; 
    } 
return $result; 
} 

這就是簡單的字符串加密。我會做的是序列化用戶的參數數組,並把它作爲在鏈接的變量:

$arr = array(
    'pet_name'=>"fido", 
    'favorite_food'=>"cat poop", 
    'unique_id'=>3848908043 
); 
$param_string = encrypt(serialize($arr)); 

$link = "/load_pet.php?params=$param_string"; 

在load_pet.php你應該做相反:

$param_string = $_GET["params"]; 
$params = unserialize(decrypt($param_string)); 

巴姆。

+0

當然,這只是一個粗略的概述..你必須處理用戶傳遞一個無效param_string的情況..例如:它不會反序列化,所以你必須抓住它。 – 2008-11-29 05:17:09