За последние 24 часа нас посетили 22443 программиста и 1149 роботов. Сейчас ищут 617 программистов ...

Как надёжно защитить файлы и выдавать их по ключу или паролю?

Тема в разделе "PHP для профи", создана пользователем kciray8, 6 июл 2016.

  1. kciray8

    kciray8 Новичок

    С нами с:
    6 июл 2016
    Сообщения:
    1
    Симпатии:
    0
    Я собираюсь продавать приложение на allsoft и возникает необходимость сделать выдачу полной версии программы по лицензионному ключу. В PHP разбираюсь не очень хорошо, сделал простой скрипт, который это реализует. Пожалуйста, посмотрите на него - есть ли какие-нибудь подводные камни у Apache\PHP которые позволят обходным путём получить этот файл или вторгнуться в БД?

    В папке private находятся exe-шники программ. Также там находится .htaccess, который блокирует доступ в эту папку по обычным запросам:

    Код (Text):
    1. Deny from all
    Далее - пользователь может составить get-запрос к файлу get.php, который проверяет ключ на наличие в таблице и выдаёт файл если всё впорядкe

    PHP:
    1. <?php
    2. $servername = "localhost";
    3. $username = "username";
    4. $password = "password";
    5. $db = "db";
    6.  
    7. $dbh = new PDO("mysql:host=$servername;dbname=$db", $username, $password);
    8.  
    9. // Check connection
    10. if ($conn->connect_error) {
    11.     die("Connection failed: " . $conn->connect_error);
    12. }
    13.  
    14. $key = $_GET["key"];
    15. $version = (int) $_GET["version"];
    16.  
    17. $stmt = $dbh->prepare("SELECT count(*) FROM `serial_keys` WHERE `key_str`= :kk");
    18. $stmt->bindParam(":kk", $key);
    19. $stmt->execute();
    20.  
    21. $number_of_rows = $stmt->fetchColumn();
    22.  
    23. if($number_of_rows == 1){
    24.     $file = "private/$version.exe";
    25.  
    26.     header('Content-Type: application/octet-stream');
    27.     header("Content-Transfer-Encoding: Binary");
    28.     header("Content-disposition: attachment; filename=\"App.exe\"");
    29.     header('Content-Length: ' . filesize($file));
    30.     readfile("$file");
    31. }else{
    32.     echo "Неверный ключ!";
    33. }

    Запрос вида site.com/get.php?key=DDD-XXX-BBB&version=1
     
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.230
    Симпатии:
    1.715
    Адрес:
    Молдова, г.Кишинёв
    Ещё можно пометить ключ в базе как использованный.
    Но лучше сделать защиту в самой программе и раздавать её без ключа, ключ требовать при запуске.
     
  3. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    @kciray8 в принципе это должно работать. только продумай случаи когда кто-то засветил ссылку с ключем. она не должна работать бесконечно и для всех. надо её экспарить.

    Денис правильно подсказывает: лучше если программа будет сама контролировать ключ. Продавай ключ активации. Пусть прога выдаёт некий machine id, который пользователь будет сообщать на сайте регистрации, в ответ получая код активации.
    у тебя будет функция выдачи лицензии
    f(machine_id, prog_version_id) => activation_code
    а внутри проги функция
    f(machine_id, prog_version_id, activation_code) => true|false
    для проверки правильности лицензии

    про то как идентифицировать комп можно нагуглить. например побыстрому нашлось:
    http://www.nextofwindows.com/the-best-way-to-uniquely-identify-a-windows-machine
    http://stackoverflow.com/questions/2004666/get-unique-machine-id
     
  4. Abyss

    Abyss Старожил

    С нами с:
    12 дек 2015
    Сообщения:
    1.298
    Симпатии:
    218
    Адрес:
    Default city
    Или добавить таблицу использований того или иного ключа.
     
  5. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @artoodetoo не думаю что нужно идентифицировать комп, просто сделать разовую ссылку для скачивания файла через обработчик где нужно ткнуть кнопку скачать файл, при этом когда тыкают на эту кнопку первым делом должен отправится, аякс запрос на обработчик который и удалит данную ссылку для доступа к скачиванию файла, а после запусится скачивание файла. Думаю лучше такой алгоритм написать чисто скачать можно будет только один раз по данной ссылке. А ещё классно что если ссылок вообще не будет существовать, их тупо выдают по факту, заплатил на сгенерированную ссылку, после скачивания удалить ссылку и всё.
     
  6. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    я вот подумал, как это сделать без проверок всяких. Ещё не пробовал. Но мне кажется, что прокатит. Надо просто создавать ярлычок на файл. Сервер отдаст файл, а раз в час проходить и убивать ярлчки, которые слишком старые.
     
  7. rodent90

    rodent90 Новичок

    С нами с:
    26 мар 2015
    Сообщения:
    533
    Симпатии:
    37
    Чексумить и по дате смотреть начало и в течении какого времени затирать. Кажись так будет удачнее.
     
  8. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    не. если чексумить это уже некие скрипты и логика. Я же предлагаю способ, при котором всё происходит "само собой".
     
  9. rodent90

    rodent90 Новичок

    С нами с:
    26 мар 2015
    Сообщения:
    533
    Симпатии:
    37
    Точняк, чексумить лучше если обновления предоставлять.
    Можно пойти путем временных файлов.
     
  10. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @igordata а чем мой вариант не вкатил?)
     
  11. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    ну там надо как-то считать хеш. А я предлагаю просто команду по крону делать и всё.
     
  12. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @igordata не надо там не чего считать, какой хеш какой крон. смотрите.

    Алгоритм.

    Выдаём чуваку ссылку, он на неё заходит создаётся файл, не знаю и записывается имя файла в бд, к примеру, и в сессию записываем уникальный идентификатор текущего зашедшего на эту ссылку, после чувак там качает файл делает что хочет, а после, когда он уходит с этой странички, ну то есть закрывает сессию, файл удаляется нахрен. Ну правда погрешность, если он случайно закроет то всё тютю :'D ну да мой способ не очень :'D
     
  13. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    @askanim у тебя бесконечные жесткие диски? симлинк.
     
  14. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @Ganzal :D нет, смотри
     
  15. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    @askanim ты в своем способе не на этом внимание акцентировал. Стало быть ты не в курсе что на дисках место может кончиться если постоянно копировать файлы для всех желающих их скачать. И более того - для каждой сессии каждого желающего скачать. Очаровательное решение.
     
  16. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    это если мы под каждого индивидуальные файлы создаём. Тут можно отдать сразу из пхп даже.
    А я описал решение для ситуации, когда файлы уже есть, их надо кому-то давать, а кому-то не давать. И вот можно волшебным образом создавать уникальные ссылки.
     
  17. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @igordata как запретить скачивание файла ? Вообще в принципе, если вводишь прямую ссылку на файл, он тупо браузером начинает тянуться, это на уровне сервера настраивается?
    --- Добавлено ---
    @Ganzal А чистить после закачки не вариант?
     
  18. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
  19. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    можно расположить сами файлы вне документрута, а в документруте будут проявляться только симлинки. Симлинк со специфическим именем, естественно, чтоб веб-сервер по этому имени сначала проверил авторизацию загрузки, а потом... прочитал симлинк как обычный файл в поток. Не нужно дергать никакой скриптовый язык для вычитки файла побайтно - веб-сервер сам с этим справится без дополнительной нагрузки.

    Чистить что? КОПИЮ ФАЙЛА удалить или симлинк? КОПИЯ ФАЙЛА будет весить столько же, сколько ОРИГИНАЛЬНЫЙ ФАЙЛ. Симлинк же будет плюс-минус кол-во символов с полному пути к ОРИГИНАЛУ в файловой системе.
     
  20. Sanchis

    Sanchis Новичок

    С нами с:
    14 мар 2016
    Сообщения:
    38
    Симпатии:
    4
    Генерируй ключ программой, заноси его в базу и активируй по запросу. Получается, первым делом продаешь ключ а уже потом при запросе к файлу проверишь есть ли этот ключ в базе и активен ли он. Копируешь файл давая ему оригинальное имя и генерируешь к нему линк. Вообще лучше лицензию делать в самой программе, иначе скачав 1 раз ее можно будет размножить
     
  21. rodent90

    rodent90 Новичок

    С нами с:
    26 мар 2015
    Сообщения:
    533
    Симпатии:
    37
    А что получилось у тебя? Целая база, сохранения, проверки на существования ключа, потом файла, потом ты генерируешь ссылку и только потом отдаешь ее и затираешь - это еще куча проверок и шлака.

    Решение довольно проще, файлы уже загружены.
    Без проверок можно сделать ярлык на файл с хешем по дате последней модификации и солью с уником пользователя которому отдаем файлик, после скачивания затирать ярлык и дату модификации и так постоянно кто скачивает файл, оно само работает, даже крон не нужен.
     
  22. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    каким образом ты будешь автоматически затирать после скачивания без крона? научи.
     
  23. rodent90

    rodent90 Новичок

    С нами с:
    26 мар 2015
    Сообщения:
    533
    Симпатии:
    37
    Таким же образом, как и создаешь.
     
  24. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    ты ответь на вопрос, пожалуйста. Я ж не умею читать мысли, и не знаю, как ты файлы создаёшь. Я не рассматривал ситуацию, когда файлы надо создавать. В моём решении файлы уже существуют. Моё решение создаёт одноразовые уникальные ссылки с помощью системных утилит. Без скриптов, условий, сравнений и прочего. Так что я не знаю ни как ты удаляешь файлы, ни как ты их создаёшь.
     
  25. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL