2010-11-10 15 views
5

używam następującą funkcję do odszyfrowywania danych na moim serwerze:Problem z funkcją PHP mcrypt

function decrypt($key, $text) { 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))); 
} 

Czytałem dużo o NIE jednak stosując EBC (i wiem, że jest przestarzała tak chciał przejść do CBC. Wystarczy do przełączania trybu..?

function decrypt($key, $text) { 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_CBC, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND))); 
} 

nie działa jednak żadne błędy są generowane ale dane zwracane jest nadal szyfrowane

Czego mi brakuje

Zaktualizowany kod - jeszcze z błędami:

$key = "hello"; 

$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM); 

function encrypt($key, $text) { 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv))); 
} 


function decrypt($key, $text) { 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($text), MCRYPT_MODE_CBC, $iv)); 
} 


$text = 12345; 

echo "Plain Number : " . $text . "<br><br>"; 

$encrypted = encrypt($key, $text); 
echo "AES Number : " . $encrypted . "<br><br>"; 

echo "Plain Number : ". decrypt($key, $encrypted) . "<br><br>"; 

to powinno działać - ale zwraca błąd:

blocksize w

blocksize w> Ostrzeżenie: mcrypt_encrypt()

[function.mcrypt-encrypt]: The IV parameter must be as long as the blocksize inblocksize in

blokuje się w

+1

Czy dane dotyczące zwrotu są takie same, jak te, które przekazałeś? Jeśli tak, to coś jest nie tak z funkcją odszyfrowywania. W przeciwnym razie działa normalnie i właśnie użyłeś niewłaściwego klucza/IV i odzyskasz śmieci. –

+0

@Marc B - tak, w rzeczywistości używam szyfrowania i odszyfrowywania na tej samej stronie, nawet w celu upewnienia się, że informacje są dobre, ale pojawiają się błędy. Spróbuję zobaczyć niektóre z poniższych sugestii. – JM4

Odpowiedz

5

Zaktualizowana kod ma problem z $iv bycia zmienna globalna, które nie jest dostępne w odpowiednich funkcji pl/dekodowania:

$key = "hello"; 

$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM); 

function encrypt($key, $text, $iv) { 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv))); 
} 

function decrypt($key, $text, $iv) { 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($text), MCRYPT_MODE_CBC, $iv)); 
} 

$text = 12345; 

echo "Plain Number : " . $text . "<br><br>"; 

$encrypted = encrypt($key, $text, $iv); 
echo "AES Number : " . $encrypted . "<br><br>"; 

echo "Plain Number : ". decrypt($key, $encrypted, $iv) . "<br><br>"; 

Albo można nadal powoływać się na globalnym $iv przez importowania go do lokalny zakres funkcji:

function encrypt($key, $text) { 
    global $iv; // or use $GLOBALS['iv] instead of $iv in the call below 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv))); 
} 

function decrypt($key, $text) { 
    global $iv; // or use $GLOBALS['iv] instead of $iv in the call below 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($text), MCRYPT_MODE_CBC, $iv)); 
} 

, ale z pewnością nie jest to zalecana praktyka, ponieważ łączy kod ze zmiennymi globalnymi.

+0

'mcrypt_create_iv' eliminuje ostrzeżenie, ale z jakiegoś powodu wydaje się być strasznie powolne. – quickshiftin

+0

Nie wiem dlaczego, ale w systemach Linux używających 'MCRYPT_DEV_RANDOM' do wywołania' mcrypt_create_iv' zajęło dobrą chwilę. Używanie 'MCRYPT_DEV_URANDOM' jest praktycznie natychmiastowe, jak można się było spodziewać. – quickshiftin

+1

Bez wątpienia zauważysz to szczególnie na maszynach wirtualnych. Wynika to z faktu, że maszyny wirtualne nie mają porządnego źródła entropii dla/dev/random. – Schodemeiss

7

Po odszyfrowaniu musisz użyć tej samej litery IV, co podczas szyfrowania. Wygląda na to, że podczas deszyfrowania generujesz nowy, losowy IV.

Dodanie lub dodanie znaku IV do tekstu zaszyfrowanego jest OK. Karty IV nie są tajne, ale powinny być unikatowe dla każdej zaszyfrowanej wiadomości i używane tylko raz.

+1

@cameron - dzięki za pomoc - będę musiał spojrzeć wstecz na IV, ale w rzeczywistości - jaki jest ogólny cel IV, jeśli już używasz klucza do zaszyfrowania pliku na początek (prawdopodobnie twój IV jest przechowywany w tym samym miejscu co same dane, które nie są zbyt bezpieczne, jeśli serwer zostanie przejęty. – JM4

+0

IV jest właśnie po to, aby zapobiec technikom kryptoanalizy statystycznej, to nie jest tajemnica, więc nie ma znaczenia, czy jest ona ujawniona.Używanie losowego IV dla każdej wiadomości oznacza, że ​​jeśli zaszyjesz ten sam komunikat dwa razy tym samym kluczem, otrzymasz inny tekst zaszyfrowany. Oznacza to, że podsłuchujący nie może szukać wzorców w sekwencji wiadomości, nawet jeśli zna IV dla każdej wiadomości. Jest to ważne, nawet jeśli nie szyfrujesz wielokrotnie tej samej wiadomości. –

+0

@cameron - istnieje nowa edycja powyżej, która nadal daje błędy nawet na tej samej stronie. – JM4

3

Czy zmieniłeś tryb również podczas szyfrowania tego tekstu?

Ponadto podczas używania MCRYPT_MODE_CBC należy użyć tego samego klucza i kodu IV podczas szyfrowania i deszyfrowania. Randomized IV nie działa z CBC.

+0

Zmieniłem także tryb szyfrowania; jednakże, do twojego ostatniego punktu, "randomizowany IV" nie działa - przykładowy kod na php.net wydaje się wskazywać inaczej (chociaż używa tripledów jako szyfru): http://www.php.net/manual/en/function. mcrypt-cbc.php – JM4

+0

Myślę, że @Dan mówił, że nie można odszyfrować z jakimkolwiek starym przypadkowym IV, musi być taki sam jak był używany do szyfrowania. EBC nie stosuje IV. –

+0

nowa edycja powyżej. – JM4