Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] szyfrowane pobieranie pliku
Forum PHP.pl > Forum > PHP
jawka7
witam chciałbym zrobic w moim serwisie cos takiego ze jesli dane konto wykpoiło dany skrypt to ma mozliwosc go pobrania ewentualnie generuje mu unikalny link do skryptu.. jednak tak aby tego pliku nie mozna bylo udostepnic osob trzecim.. jak sie za to zabrac? nigdy nie mialem do czynienia z podobnym skryptem.
CuteOne
1. Możesz umożliwić ściąganie takiego pliku tylko z danego IP
2. Nie wystawiać pliku do ściągania smile.gif

Innych możliwości nie widzę czyli wychodzi na to, że się nie da ^-^
jawka7
hm a jakby dany plik skrypt skopiowal w konkretne miejscce na pewien czas taki plik tymczasowy i np po 5 min usunął go, teraz pytanie jak zabezpieczyc plik zrudłowy aby mi go nikt nie wykradł, jakby ktos wiedział jak zrobic taki system podobny ro Rapida ;/
CuteOne
Czekaj czekaj.. chcesz udostępnić plik tylko osobie zalogowanej, która wykupiła ten bonus? jeżeli tak to wystarczy link typu index.php?p=download&file=10000

w pliku download [tym ze ścieżki] :
- umieszczasz sprawdzanie czy użytkownik jest zalogowany
- pobieranie z bazy danych adresu pliku o id = 10000
- sprawdzenie czy użytkownik jest autoryzowany do ściągnięcia tego pliku
- wysłanie pliku
jawka7
- sprawdzenie czy użytkownik jest autoryzowany do ściągnięcia tego pliku

co masz w tym podpuncie na mysli jak taka autoryzacje wykonac?
andycole
Na przykład tworzysz 3 tabele:
-użytkownicy
-pliki
-uzytkownicy_pliki (id_uzytkownika, id_pliku)

Gość najpierw się loguje do systemu, a później sprawdzasz czy może plik o danym ID ściągnąć czyli czy jest w tabeli uzytkownicy_pliki odpowiedni rekord.
jawka7
no tak to jest jane ale chodzi mi tez o to aby ten link do pliku nie wszedl w siec tak aby kazdy mogl go sciagnac
kiler129
Cytat(jawka7 @ 3.10.2010, 09:27:11 ) *
no tak to jest jane ale chodzi mi tez o to aby ten link do pliku nie wszedl w siec tak aby kazdy mogl go sciagnac

To dodaj do crontaba zadanie które będzie usuwać.
Czas expire linku licz dla 1Mb, np.:

700*1024/120 ~= 5973sec
Teraz pobierasz czas za pomocą time(), dodajesz wynik i zapisujesz clay timestamp do mysql.
W skrypcie odpalanym z crontaba sprawdzasz wszystkie rekordy po kolei i czy ich expire_time jest < lub = aktualnemu czasowi. Jeśli tak usuwasz rekord.
yevaud
tworzysz sobie download.php gdzie Twoj skrypt wysyla plik o ktory go prosza

unikalny link do pliku robisz tak:
1. dodajesz sol do linka, hashujesz go
2. linki do pliku beda postaci download.php?plik=nazwapliku&hash=generowanyhash
3. przed wyslaniem pliku sprawdzasz czy hash sie zgadza

unikalny link do pliku dla zalogowanego uzytownika tak:
1. dodajesz sol do linka ORAZ dodajesz do tego id zalogowanego usera, hashujesz go
2. linki do pliku beda postaci download.php?plik=nazwapliku&hash=generowanyhash
3. przed wyslaniem pliku sprawdzasz czy hash sie zgadza

unikalny link do pliku z terminem waznosci, dla zalogowanego usera tak:
1. dodajesz sol do linka ORAZ dodajesz do tego id zalogowanego usera ORAZ dodajesz czas wygenerowania linku, hashujesz go
2. linki do pliku beda postaci download.php?plik=nazwapliku&hash=generowanyhash&czaswygenerowania=czas
3. przed wyslaniem pliku sprawdzasz czy hash sie zgadza i czy czas jest odpowiednio ustawiony w stosunku do czasu aktualnego

przez sam link rozumiem download.php?plik=nazwapliku, dlatego w przypadku trzecim oddzielilem hashowanie linku od hashowania czasu, ale nic nie stoi na przeszkodzie zeby hashowac calosc jak leci - nawet jest to wskazane

mozesz uzyc do tego wszystkie takze bazy danych i sprawdzac czy linki spelniaja warunki jakie tylko sobie wymyslisz, ale jak widac - nie musisz
andycole
Cytat(yevaud @ 3.10.2010, 12:06:57 ) *
unikalny link do pliku z terminem waznosci, dla zalogowanego usera tak:
1. dodajesz sol do linka ORAZ dodajesz do tego id zalogowanego usera ORAZ dodajesz czas wygenerowania linku, hashujesz go
2. linki do pliku beda postaci download.php?plik=nazwapliku&hash=generowanyhash&czaswygenerowania=czas
3. przed wyslaniem pliku sprawdzasz czy hash sie zgadza i czy czas jest odpowiednio ustawiony w stosunku do czasu aktualnego


Dobrze rozumiem, że ten celem tego hash'a jest weryfikacja czy zmienna w czaswygenerowania jest poprawnym (niezedytowanym przez złośliwego usera) czasem?
Bardzo fajny i przydatny pomysł.
jawka7
no fajny i ciekawy tylko teraz ja musze pomyslec jak ten twoj post odhashowac ;d
yevaud
Hej,
opisze troche dokladniej o co mi chodzi

Cytat
Dobrze rozumiem, że ten celem tego hash'a jest weryfikacja czy zmienna w czaswygenerowania jest poprawnym (niezedytowanym przez złośliwego usera) czasem?

dokladnie tak, w tym przypadku hash'a uzywam podobnie jak podpisu cyfrowego. Unikalna sol(sól) uniemozliwia uzytkownikom podrobienie hasha/podpisu

generalnie widzialbym to jakos tak(pisze z palca tama wersje mocno robocza), wersja dla zalogowanego usera

  1. $salt = 'dr5678iolkmnbvftyuio';
  2. function generujLink($plik, $userid)
  3. {
  4. global $salt;
  5. $hash = sha1($salt.$plik.$userid);
  6. $hash = substr($hash, 0, 8); // zeby nie byl taki dlugi
  7. return "download?plik=$plik&hash=$hash";
  8. }
  9.  
  10. function wyplujPlik($plik, $userid, $hash)
  11. {
  12. global $salt;
  13. $hash2 = sha1($salt.$plik.$userid);
  14. $hash2 = substr($hash, 0, 8); // zeby nie byl taki dlugi
  15. if ($hash2 == $hash)
  16. {
  17. header('Content-type itp');
  18. readfile($plik);
  19. }
  20. }
  21.  
  22. // uzycie
  23.  
  24. // puszczam link tak
  25. echo '<a href="' . generujLink('plik.txt', $_SESSION['userid']) .'">link</a>';
  26.  
  27. // wypluwam tak
  28. wyplujPlik($_GET['plik'], $_SESSION['userid'], $_GET['hash']);
  29.  
jawka7
a jak moge zabezpieczyc folder w którym beda znajdowaly sie pliki z danymi? CHMOD? jesli tak to jaki powinien byc? a i na poczatku ten salt mogłby byc np losowym ciagiem znakow byloby bezpieczniej winksmiley.jpg
yevaud
dane nie musza byc w ogole dostepne z poziomu http, wazne zeby php mialo do nich dostep

sugerujesz ze ten salt nie jest losowy ?
jawka7
mozna zmodyfikowac troche twoj skrypt winksmiley.jpg

$salt = md5(uniqid(rand(), true));

zapisac salt do sesji i przy wywolaniu linku zrobic tak aby nie wygenerowal sie nowy salt tylko aby sprawdzal aktualny i czy z nim si ezgadza wygeberowany link winksmiley.jpg
yevaud
mozna, wtedy link bedzie dzialal tak dlugo jak istnieje sesja uzytkownika
dariuszp
1. PYTANIE DO KOMENTUJĄCYCH
Dlaczego Wy tak bardzo komplikujecie tak prostą sprawę ? Trzeba mieć masochistyczne skłonności by skorzystać z którejkolwiek rady. Oczywiście to moje subiektywne zdanie.

2. PYTANIE DO AUTORA
Czy masz możliwość wprowadzania zmian na serwerze produkcyjnym ? (tam gdzie ma to wszystko działać, bo jasne że z serwerem testowym robisz co chcesz).

3. SUGESTIA
Zapoznajcie się z tematem odrobinę zanim zaczniecie dawać dziwne rady. Przez chwilę myślałem że z autora tematu się po prostu nabijacie (moja subiektywna ocena).

4. MOJA RADA - JEŻELI NIE MASZ MOŻLIWOŚCI WPROWADZANIA ZMIAN NA SERWERZE
Jeżeli chodzi o bardzo małe pliki to można wykorzystać PHP. Za pomocą header wysyłasz odpowiednie nagłówki takie jak:

Kod
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Description: File Transfer");
header("Content-Length: ".filesize($url));
header("Content-Transfer-Encoding: binary");
header("Content-Disposition: attachment; filename=\"".basename($url)."\"");


Następnie za pomocą fopen() otwierasz sobie plik który jest pod $url i w pętli linia po linii wypisujesz go. Tu należy pamiętać o drobiazgu. NIC przed lub PO pliku nie powinno zostać wyświetlone. Jeden durny biały znak i plik będzie błędnie zapisany u użytkownika. Z uwagi na to że będziesz korzystał z pętli a sam plik chwilę się będzie wypisywał użytkownikowi, możesz przekroczyć czas działania skryptu PHP co również zniszczy zawartość pliku (przerwany transfer + dodatkowe znaki jak treść błędu itp, kwestia ustawień serwera).

Użytkownik nie dostanie bezpośredniego linku na serwerze. Sam plik może być trzymany w dowolnym miejscu. Dodatkowo możesz w dowolny sposób decydować czy rozpocząć jego wysyłanie użytkownikowi czy nie.

5. MOJA RADA 2 - JEŻELI MOŻESZ WPROWADZAĆ ZMIANY NA SERWERZE
Metoda 1 ma jedną wadę. Nie wyślesz nią dużych plików a im gorszy transfer ma użytkownik tym większa szansa że wystąpi problem. Istnieje sposób na jego ominięcie. Trzeba sobie doinstalować rozszerzenie xSendFile do Apache. O xSendFile poczytasz w Google. Sporo piszą na jego temat. Jak nic się nie zmieniło to obecna wersja pozwala na wysyłanie plików DO 4GB. Wersja beta przekracza ten limit pozwalając na wysyłanie na prawdę dużych plików.


Co do całej reszty to już Twoja wola jak to zabezpieczysz. Obie metody są wygodne i pewne.
jawka7
z tym ze te z hash rozumiem a twoich nie winksmiley.jpg czy pliki o wielkosci mniej wiecej 10 mb beda przeszkadzac?
yevaud
Cytat(dariuszp @ 4.10.2010, 14:56:18 ) *
1. PYTANIE DO KOMENTUJĄCYCH
Dlaczego Wy tak bardzo komplikujecie tak prostą sprawę ? Trzeba mieć masochistyczne skłonności by skorzystać z którejkolwiek rady.

kolega pytal o to jak zabezpieczyc dostep do plikow, od Ciebie otrzymal odpowiedz jak wysylac pliki za pomoca php. Sprawy sa oczywiscie powiazane, ale generalnie to co ma piernik do wiatraka. Pomysly byly rozne, ale dotyczyly tematu smile.gif

sugerujesz ze Twoje rozwiazanie
Cytat
  1. Następnie za pomocą fopen() otwierasz sobie plik który jest pod $url i w pętli linia po linii wypisujesz go. Tu należy pamiętać o drobiazgu. NIC przed lub PO pliku nie powinno zostać wyświetlone. Jeden durny biały znak i plik będzie błędnie zapisany u użytkownika. Z uwagi na to że będziesz korzystał z pętli a sam plik chwilę się będzie wypisywał użytkownikowi, możesz przekroczyć czas działania skryptu PHP co również zniszczy zawartość pliku (przerwany transfer + dodatkowe znaki jak treść błędu itp, kwestia ustawień serwera).


jest bardziej skomplikowane niz moje ktore zapronowalem zeby wysylac plik?
  1. header('Content-type itp');
  2. readfile($plik);

oczywiscie headery wstawiasz jakie potrzebujesz, nie znamy nawet mime tych plikow

Cytat
Dodatkowo możesz w dowolny sposób decydować czy rozpocząć jego wysyłanie użytkownikowi czy nie.[...]Co do całej reszty to już Twoja wola jak to zabezpieczysz

tylko ze kolega pytal jak zabezpieczyc, wiec o ta cala reszte ktora raczyles pominac

Cytat
Trzeba sobie doinstalować rozszerzenie xSendFile do Apache. O xSendFile poczytasz w Google. Sporo piszą na jego temat. Jak nic się nie zmieniło to obecna wersja pozwala na wysyłanie plików DO 4GB. Wersja beta przekracza ten limit pozwalając na wysyłanie na prawdę dużych plików.

jedyna rzecz ktora wnosi cos do tematu smile.gif
jawka7
Jak dla mnie bardziej widzi sie twoj skrypt yevaud ktory mi podałes a co do header'ow nie chce krytykowac bo byc moze jest to lepsze moze nie ale ja nie wglebilem sie jeszcze w ten dział php winksmiley.jpg jednakze zastosuje twoj skrypt z hashem.

Jak dla mnie na tym forum powinien byc podany jakis artykul o tej tematyce zabezpieczen plikow.

I tu jest mój apel do administracji ;P

Dziekuje serdecznie za pomoc odłóżcie kosy na bok, TEMAT ZAMYKAM winksmiley.jpg
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.