2008-11-29 7 views
7

Buduję system z kodem źródłowym, który daję w sieci na dostarczanie adoptowalnych wirtualnych zwierząt. System będzie własnością głównie dzieci. Ponieważ chcę, aby był on użyteczny dla absolutnie początkujących programistów, w moim systemie jest kilka ograniczeń złożoności: nie może korzystać z bibliotek, które nie są zwykle dostarczane z PHP, i nie może dotykać bazy danych lub pisać do innych stałych pamięci .Proste szyfrowanie w PHP

Po przyjęciu każdego zwierzaka gość otrzyma losowo jedną z serii nieco odmiennych odmian tego zwierzaka. Odmiany wyglądają początkowo tak samo, ale z czasem stają się coraz bardziej zróżnicowane. Użytkownik otrzyma krótki kod w języku HTML, który łączy się z obrazem zwierzaka. Ponieważ nie ma stałej pamięci dostępnej po stronie serwera, łącze do obrazu użytkownika musi zawierać wszystkie informacje, aby ustalić, która wersja zwierzęcia się skończyła.

W tej chwili adres URL zawiera identyfikator zwierzaka i identyfikator odmiany, którą otrzymał użytkownik. Problem polega na tym, że porównując kody ze sobą, użytkownicy mogą dowiedzieć się, który z nich znalazł się w tej samej odmianie. Ponieważ niektóre odmiany są rzadsze niż inne, użytkownicy mogą łatwo zauważyć rzadkie odmiany, zanim różnica będzie nawet widoczna.

To, co chciałbym, to system szyfrowania dla szczegółów w adresie URL. Coś, co przesłania identyfikator odmiany, aby każdy użytkownik otrzymał inny adres URL z dużym prawdopodobieństwem. Myślałem o używaniu identyfikatora wariancji (3 lub 4 bity) jako niskich bitów lub wysokich bitów dużej liczby losowej, ale użytkownicy zauważą wzór w tym. Idealnie byłoby by system szyfrowania był sparametryzowany tak, aby każda instalacja mojego systemu używała nieco innego szyfrowania.

Biblioteka mcrypt PHP prawdopodobnie zawierałaby w sobie coś użytecznego, ale nie wydaje się być bardzo popularna wśród hosterów.

Czy istnieje prosty, sparametryzowany, zaciemnianie/szyfrowanie, którego mogę użyć tutaj?

Odpowiedz

9

Jeśli spodziewasz się stosunkowo niskiego poziomu zaawansowania, możesz wykonać bardzo proste szyfrowanie "xor" i "zapisać" klucz jako część adresu URL. Następnie możesz po prostu użyć php's rand() lub/dev/random lub cokolwiek innego, aby wygenerować klucze.

Użytkownicy o niskim poziomie zaawansowania nie będą w stanie zorientować się, że wszystko, co trzeba zrobić, to ustawić dolną połowę identyfikatora zwierzęcia w górnej połowie, aby uzyskać wartość, którą można porównać do znajomych. Sądzę, że większość ludzi, którzy byliby w stanie rozpoznać, co się dzieje, nie potrzebowałoby czasu, aby to rozgryźć, a ci ludzie i tak są poza twoimi docelowymi odbiorcami.

Edycja: Jeśli to nie było oczywiste, mówię, że dajesz inny klucz do każdego zwierzaka (ponieważ podanie tego samego nie rozwiąże problemu). Jeśli więc wariacja dla zwierząt domowych (petvar) jest liczbą 16-bitową, generujesz 16-bitową liczbę losową (rnd), następnie robisz to: petvar = (petvar^rnd)<<16 | rnd;, a następnie możesz cofnąć tę operację, aby wyodrębnić rnd, a następnie petvar^rnd, i następnie ponownie lub ponownie, aby uzyskać oryginalny petvar.

+0

Brzmi jak dobra strategia. Mogłem również XOR cały ciąg za pomocą klucza specyficznego dla instalacji. Twoje intuicje dotyczące poziomu zaawansowania "atakujących" są bardzo poprawne .. :) – thenickdude

2

Dlaczego po prostu nie dać każdemu użytkownikowi długiego, losowego identyfikatora, a następnie zapisać wszystkie szczegóły dotyczące swojego zwierzaka na serwerze? Najlepszą praktyką nie jest przechowywanie niczego w adresie URL, szyfrowanie lub nie. Wszystko, czego potrzebujesz, to identyfikator sesji.

+0

Oczywiście, to właśnie robię na własnym serwerze. Ale chcę mieć system, który dzieci mogą używać na własnym serwerze, aby rozdawać zwierzaki, nawet jeśli nie ma przyzwoitego miejsca na przechowywanie: bazy danych nie zawsze są dostępne u darmowych dostawców i są trudne do skonfigurowania, płaskie przechowywanie plików wymaga zbyt wiele kodu . – thenickdude

16

Szukasz "szyfrowania jednorazowego". Wymaga klucza i dodaje modulus do znaków, aby utworzyć zaszyfrowany ciąg.

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; 
} 

To proste szyfrowanie ciągów.Co chciałbym zrobić jest serializować tablicę parametrów użytkownika i przekazać go jako zmienną w linku:

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

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

W load_pet.php trzeba zrobić odwrotnie:

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

Bam.

+0

Oczywiście jest to tylko przybliżony zarys. Będziesz musiał obsłużyć przypadek, w którym użytkownik przekazuje nieprawidłowy parametr param_string .. np .: nie będzie on odserializowany, więc musisz go złapać. –

+1

Nie widzę tutaj niczego, co dałoby różne wyniki dla tego samego wejścia, czego właśnie szukam. – thenickdude

+0

Przepraszam, źle zrozumiałem .. :) – thenickdude