2009-09-07 15 views
28

Moja aplikacja (oczywiście) używa unikalnego identyfikatora do rozróżniania rekordów. Ten identyfikator UID jest przekazywany między innymi w adresach URL (na przykład ./examplepage.php?UID=$example_int).Szyfrowanie dwukierunkowe w PHP

Podczas gdy oczywiście mam sprawdzanie poprawności po stronie serwera, aby upewnić się, że klienci nie mają dostępu do danych innych klientów, czy istnieje dwukierunkowa metoda szyfrowania, której mogę używać w PHP do przekazywania tylko zaszyfrowanych identyfikatorów UID (np. ./examplepage.php?EUID=$encrypted_int), aby jeszcze bardziej zmniejszyć prawdopodobieństwo, że ktoś pomyśli: "Hej, co się stanie, jeśli zwiększę tę liczbę całkowitą?"

TIA.

+0

odrzucono, ponieważ nie sądziłem, że rozmowa zakończyła się tak naprawdę, że chodzi o szyfrowanie dwukierunkowe ... –

Odpowiedz

-3

Umieszczenie hasza obok identyfikatora, aby zapewnić jego bezpieczeństwo, lub dopełnienie identyfikatora dodatkowymi danymi, a nawet przekonwertowanie identyfikatora na szesnastkowy, będzie działało całkiem dobrze, tak myślę.

+2

Dzięki, dobry telefon do konwersji na heks. – benjy

+0

Mimo że nie chroniłoby to nikogo przed "tech savieve", aby spróbować następny numer heksadecymalny. Po prostu zmieniasz podstawy, pozostaje "potencjalny" problem. – rogeriopvl

+5

@benjy każdy, kto ma inicjatywę zwiększania UID, natychmiast rozpozna heks lub wyściełane int. Naprawdę powinieneś robić to, co sugerował @cel. Lub po prostu generowanie nieprzypadkowych, nieprzewidywalnych identyfikatorów UID. – bucabay

3

Podczas gdy PHP obsługuje wiele dwukierunkowych algorytmów haszujących, nie widzę, aby były użyteczne w tym przykładzie. Co trzeba zrobić, to:

  1. obciążenia wiersz z pamięci przez przewidzianego id
  2. Sprawdź, czy właściciel rzędu jest uwierzytelniony użytkownik, a jeśli nie wyjątek i informuje użytkownika, aby nie zrobić ponownie

Ale jeśli twoje serce jest ustawione na mieszanie, wybierz jeden z algorytmów provided.

+0

Dzięki za sugestię. Właściwie to już robię, ale chciałem jeszcze jeden sposób, aby odradzić użytkownikom komunikację z tą wartością. – benjy

+0

Pewnie. Zwykle nie przejmuję się takimi rzeczami. Nie ma małych obrażeń, które może zrobić użytkownik, wykonując mieszanie z identyfikatorami, jeśli masz odpowiednie listy ACL. –

+0

czy pierwszy krok nie byłby bardziej skuteczny? –

27

Nie trzeba szyfrowania dwukierunkowe - szyfrowanie jest za utrzymanie tajemnicy, ale to, czego naprawdę szukasz tu jest autentyczność.

HMAC (zasadniczo skróty klawiszowe) są jednym ze sposobów uzyskania autentyczności kryptograficznej. Dołącz do UID z HMAC UID (PHP ma HMAC implementation), używając klucza, który zna tylko serwer. Na początku każdego wniosku sprawdź HMAC.

Zasadniczo użyj odpowiedniego narzędzia do prawidłowej pracy.

+0

TO WYMAGA DODATKOWEGO POLA DB. Zgadzam się z tym, ale wymaga to przechowywania w dodatkowej dziedzinie. –

+0

@AlexV: Nie działa, ponieważ serwer może ponownie obliczyć HMAC po otrzymaniu żądania. – caf

85

PHP 5.3 wprowadził nową metodę szyfrowania, która jest naprawdę łatwa w użyciu: openssl_encrypt i openssl_decrypt. To nie jest dobrze udokumentowane, więc oto prosty przykład:

$textToEncrypt = "My super secret information."; 
$encryptionMethod = "AES-256-CBC"; // AES is used by the U.S. gov't to encrypt top secret documents. 
$secretHash = "25c6c7ff35b9979b151f2136cd13b0ff"; 

//To encrypt 
$encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash); 

//To Decrypt 
$decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash); 

//Result 
echo "Encrypted: $encryptedMessage <br>Decrypted: $decryptedMessage"; 

wybrałem 256-AES, bo to stały i szybki. Został przyjęty przez rząd Stanów Zjednoczonych do szyfrowania ściśle tajnych dokumentów. Jest szybki biorąc pod uwagę maszynę i oprogramowanie.Oto lista dostępnych metod szyfrowania:

AES-128-CBC, AES-128-CFB, AES-128-CFB1, AES-128-CFB8, AES-128-ECB, AES-128-OFB, AES- 192-CBC, AES-192-CFB, AES-192-CFB1, AES-192-CFB8, AES-192-ECB, AES-192-OFB, AES-256-CBC, AES-256-CFB, AES-256- CFB1, AES-256-CFB8, AES-256-ECB, AES-256-OFB, BF-CBC, BF-CFB, BF-ECB, BF-OFB, CAMELLIA-128-CBC, CAMELLIA-128-CFB, CAMELLIA- 128-CFB1, CAMELLIA-128-CFB8, CAMELLIA-128-ECB, CAMELLIA-128-OFB, CAMELLIA-192-CBC, CAMELLIA-192-CFB, CAMELLIA-192-CFB1, CAMELLIA-192-CFB8, CAMELLIA-192- ECB, CAMELLIA-192-OFB, CAMELLIA-256-CBC, CAMELLIA-256-CFB, CAMELLIA-256-CFB1, CAMELLIA-256-CFB8, CAMELLIA-256-ECB, CAMELLIA-256-OFB, CAST5-CBC, CAST5- CFB, CAST5-ECB, CAST5-OFB, DES-CBC, DES-CFB, DES-CFB1, DES-CFB8, DES-ECB, DES-EDE, DES-EDE-CBC, DES-EDE-CFB, DES-EDE- OFB, DES-EDE3, DES-EDE3-CBC, DES-EDE3-CFB, DES-EDE3-CFB1, DES-EDE3-CFB8, DES-EDE3-OFB, DES-OFB, DESX-CBC, RC2-40-CBC, RC2-64-CBC, RC2-CBC, RC2-CFB, RC2-ECB, RC2-OFB, RC4, RC4-40, SEED-CBC, SEED-CFB, SEED-ECB, SEED-OFB, aes-128-cbc, aes-128-cfb, aes-128-cfb1, aes-128-cfb8, aes-128-ecb, aes-128-ofb, aes-192-cbc, aes-192- cfb, aes-192-cfb1, aes-192-cfb8, aes-192-ecb, aes-192-ofb, aes-256-cbc, aes-256-cfb, aes-256-cfb1, aes-256-cfb8, aes-256-ecb, aes-256-ofb, bf-cbc, bf-cfb, bf-ecb, bf-ofb, kamelia-128-cbc, kamelia-128-cfb, kamelia-128-cfb1, kamelia-128- cfb8, kamelia-128-ecb, kamelia-128-ofb, kamelia-192-cbc, kamelia-192-cfb, kamelia-192-cfb1, kamelia-192-cfb8, kamelia-192-ekba, kamelia-192-ofb, kamelia-256-cbc, kamelia-256-cfb, kamelia-256-cfb1, kamelia-256-cfb8, kamelia-256-ecb, kamelia-256-ofb, ct5-cbc, ct5-cfb, cis5-ecb, cast5- ofb, des-cbc, des-cfb, des-cfb1, des-cfb8, des-ecb, des-ede, des-ede-cbc, des-ede-cfb, des-ede-ofb, des-ede3, des- ede3-cbc, des-ede3-cfb, des-ede3-cfb1, des-ede3-cfb8, des-ede3-ofb, des-ofb, desx-cbc, rc2-40-cbc, rc2-64-cbc, rc2- cbc, r C2-CFB, RC2, ECB, RC2-OFB RC4, rc4-40, nasiona CBC nasion CFB nasion EBC nasion OFB


ważna aktualizacja !!!

Dziękuję Hobo i Jorwinowi za wskazanie, że w PHP 5.3.3> jest nowy parametr, który sprawia, że ​​ta funkcja jest trochę bezpieczniejsza.

Jorwin odwoływać ten link w his comment, a tu jest wyjątek, który ma zastosowanie:

W 5.3.3 dodali nowy parametr, string $iv (inicjalizacji wektor) real parametry: string openssl_encrypt (string $data , string $method , string $password, bool $raw_output = false, string $iv)

Jeśli brak jest $iv, wyświetlane jest ostrzeżenie: "Używanie pustego wektora inicjującego (iv) jest potencjalnie niebezpieczne i niezalecane".

Jeśli $iv jest zbyt krótkie, kolejne ostrzeżenie: „IV przekazywana jest długa zaledwie 3 bajty, szyfr oczekuje IV dokładnie 8 bajtów, wyściółka z \ 0”

samo IV powinny być stosowane w openssl_decrypt()

+0

Używanie tego jako pokazu daje mi ostrzeżenie "Używanie pustego wektora inicjującego (iv) jest potencjalnie niebezpieczne i niezalecane". Czy to nowy parametr? Czy ta odpowiedź powinna zostać zaktualizowana? – Hobo

+2

@Hobo - Masz rację, wpadłem na ten sam problem. To jest bardziej szczegółowe wyjaśnienie. Dziękuję espradley za odpowiedź. http://php.net/manual/en/function.openssl-encrypt.php#104438 – Joe

+0

@Jowin - absolutnie w porządku. Jestem na php 5.2.2, ale od 5.3.3 rzeczywiście będziesz musiał podać 5. parametr lub otrzymać ostrzeżenie. To tylko ostrzeżenie, więc nie złamie aplikacji za każdym razem, ale bezpieczniej jest ją przekazać. – espradley

0

Po pierwsze, encrypting URL parameters is usually a bad idea, a osobne wyszukiwanie (na podstawie kolumny indeksu CHAR wygenerowanej przez CSPRNG) jest lepsze dla 99,9% przypadków użycia.

Z tym powiedział: Tak, można użyć rozszerzenia OpenSSL (don't use mcrypt) do szyfrowania danych like espradley suggested, jednak chciałbym Cię ostrzec, aby nie ograniczać się do samego szyfrowania.

Encryption without message authentication is dangerous, zwłaszcza jeśli ufasz użytkownikowi końcowemu zaszyfrowanego tekstu.

Rozwiązaniem jest zatem użycie authenticated encryption, do którego można uzyskać łatwy dostęp za pomocą libsodium, available on PECL.

Jeśli nie możesz z jakiegokolwiek powodu zainstalować rozszerzenia PECL, istnieją dwie biblioteki PHP do wyboru: defuse/php-encryption i zend-crypt. Oba oferują standardy zgodne z uwierzytelnianym szyfrowaniem i oba są bezpieczne w użyciu (dla tego, co jest warte, często wykonuję code audits for cryptography implementations w PHP, nie jestem po prostu jakąś przypadkową osobą w Internecie).