Защита PHP скриптов от копирования (Rating: +10)

Print RSS
Бывает так, что вам неохота предоставлять исходные коды проектов, которые вы разрабатывали. Для этого можно использовать программы-обфускаторы, о которых недавно шла речь.
А бывает, что вам не так хочется закрыть исходный код, как защитить скрипт от копирования. На мой взгляд, сокрытие исходного кода, в большинстве случаев, не имеет смысла без защиты от копирования. Некоторые обфускаторы, шифрующие код (а не просто коверкающие), имеют возможность лочить скрипт под определенный домен или айпишник. Но, во-первых, мы же не хотим для каждого домена перешифровывать все исходники? Во-вторых, мне удалось разлочить эту защиту одной строкой в начале скрипта:
$_SERVER['HTTP_HOST']='разрешенный домен';
Я долго искал в интернете решение для защиты от копирования. На форумах этот вопрос часто обсуждался, в основном, задавали его новички, а опытные (видимо) программисты отвечали "— Ты дурак, кому нужен твой код. Учи матчасть, да и вообще php-скрипты ничего не достойны!". Что ж, подумал я. Наверное, действительно нельзя. Но подождите, тот же Битрикс (фу) выдает лицензии на отдельные сайты, при этом вы получаете открытый исходный код после покупки лицензии. Что же мешает скопировать его на несколько своих сайтов? Я не знаю, а если вы знаете — скажите мне пожалуйста.
В итоге, делать защиту от копирования пришлось самому. Я поставил такие исходные условия задачи:
Скрипт, очевидно, должен быть зашифрован, например Зендом. Но мне понравился Lock It — во-первых, он не требует Зенд Оптимайзера, и, во-вторых — стоит недорого. Но сейчас речь не о том, как шифровать скрипт, а как защитить его от копирования. Поэтому идем дальше, просто будем считать, что исходный код закрыт. Очевидно, что это необходимое условие.
Я хочу выдавать ключ (я назову его лицензией) на каждый экземпляр скрипта. То есть я хочу каждому человеку отдавать только лицензию, а скрипт пусть валяется во всеобщем доступе.
Лицензию привязывать к домену, но если у домена есть синонимы — скрипт должен работать и при обращении через них. Главное, чтоб это был один и тот же экземпляр скрипта.
Никаких коннектов на другой (мой) сервер. Скрипт должен быть самодостаточным.
Никакого доверия скрипта к серверным переменным или переменным окружения во время проверки лицензии. Их можно легко переопределить.
Решение
1. Выдача лицензии и проверка действительности лицензии скриптом
Я создаю ключ к домену приблизительно таким образом:
$key = md5($domain.$secretword);
Cкрипт проверяет свою лицензию так:
$key == md5($domain.$secretword);
Действительно, некрасиво хранить $secretword в самих скриптах. Поэтому здесь можно использовать шифрование с открытым ключом. При выдаче лицензии я буду подписывать ее своим закрытым ключем, а скрипт, при проверке лицензии, открытым ключем будет проверять действительность лицензии. Но я не нашел в стандартном комплекте PHP никаких функций шифрования с открытым ключом, даже RSA (я слепой?). Если поможете — буду благодарен.
Итак, скрипт проверил правильность лицензии. То есть, подходит ли указанный ключ к указанному домену. Идем дальше.
2. Проверка домена
Как скрипт может проверить, лежит ли он на указанном домене? У нас нет доверия к $_SERVER['HTTP_HOST'].
Так же, по условиям — никаких коннектов на другой сервер. Значит, коннектимся сами к себе по предполагаемому домену, и проверяем мы ли там находимся smile
А точнее:
1) сохраняем случайное число на сервре (например, во временном файле)
2) обращаемся по адресу наш_домен.ру/наш_скрипт.php?action=скажи_число
3) проверяем, какое число нам отдают по этому адресу. Если оно соответсвует тому, что мы сохранили, значит, по адресу находимся мы smile
0) нулевым пунктом надо добавить отдачу сохраненного числа, если нас вызвали с параметром action=скажи_число
Я немного упростил алгоритм, на самом деле для каждого обращения к скрипту нужно отдельно учитывать эти случайные числа.
Теперь скрипт знает, что лицензия действительна, и что он лежит на соответствующем домене. Основная задача решена!
Вы скажите — wtf, скрипт при каждом обращении будет дергать сам себя? Действительно, жестоко как-то. Поэтому:
3. Временная лицензия
При первом обращении, если проверка прошла успешно, скрипт сохраняет во временном файле временную лицензию.
Временная лицензия представляет собой что-то ноподобие md5(сегодняшняя_дата, домен, секретное слово).
Теперь при каждом запросе мы проверяем только временную лицензию, которая действительна в течение дня. Как только со временной лицензией что-то неладное (поменяли, удалили, прошли сутки) — скрипт опять проверит всё серьезно и сохранит новую временную лицензию.
4. Выполнение скрипта на локальном компьютере без лицензии
Было бы идеально, если бы скрипт не требовал лицензии при запуске на локальном компьютере. Зачем, спрашивается, человеку требовать с меня лицензию, если он просто хочет протестировать скрипт на своем компьютере? Он должен скачать его, и пользоваться. А вот когда он поставит скрипт на сервер, тогда и прийдет ко мне.
Я не знаю как решить эту задачу. У меня пока есть 3 варианта решения, но они мне не нравятся:
1) Если скрипт лежит на домене без точек (типа http://myscript/) — считать, что это виртуальный домен, значит, скорее всего, это локальное тестирование. Недостаток этого метода — умельцы создадут виртуальный домен на своем сервере, а настоящий домен сделают синонимом. Так же, непонятно что делать с доменом localhost.
2) Проверка $_SERVER["REMOTE_ADDR"]. Проверяем наличие '127' в начале ip-адреса. Недостаток — можно переопределить эту переменную перед выполнением скрипта.
3) Смешно, но можно проверить операционную систему сервера. И разрешить выполнение под Windows. Только не бейте меня, это всего лишь вариант.
Added:
Rating: +10
Views: 3483
Comments (11) »