Думаю, многие сталкивались с тем, что иногда необходимо защитить ваш скрипт от копирования, и вы использовали разные Ioncube, PHPLockit, но многим неудобно каждый раз кодировать. Понимаю, что в Ioncube есть такая штука, благодаря которой можно генерировать ключи безопасности и т.д., но многим невыгодно покупать или же пользоваться чужими услугами, а то мало ли, все бывает.
Некоторым хочется кодировать не весь код, а лишь его часть, и для этого многие используют такой «массив» для защиты:
$_SERVER['HTTP_HOST']
Но его легко обойти:
$_SERVER['HTTP_HOST']='разрешенный домен';
Поэтому есть решение данной проблемы, и её может решить любой человек с начальным знанием PHP, MySQL.
В итоге у нас получится:
- Скрипт будет закодирован путем обфускатора, который посылает API запрос к сайту, где API ищет доменное имя и ключ в базе данных; если он есть, то скрипт будет работать, если нет, то он будет переадресовывать основному сайту (пример будет таким: domain.com/api.php?domain=mysite1.ru&key=4024B-C0876-4FF0C-9A298-80EFA);
- Также у нас будет скрипт api.php, который будет отвечать за работу проверки лицензии и т.д.;
- Также хочу выделить лицензионный ключ, который мы будем получать. Лицензионный ключ — это md5 хэш домена, который будет проверятся через api, а в базе данных будет записан лишь сам домен и его статус.
Решение
1. Выдача лицензий и проверка действительности скрипта через api:
<?php $config = array( 'host' => 'localhost', 'user' => 'root', 'pass' => '', 'base' => 'lic' ); $db = new mysqli($config['host'], $config['user'], $config['pass'], $config['base']); if($db->connect_errno) { exit('Ошибка: Не удалось подключиться к базе данных!'); } $db->set_charset("utf8"); class Main { public function keygen($domain){ $key[0] = strtoupper(md5($domain)); $key[1] = substr($key[0], 0, 5); $key[2] = substr($key[0], 5, 5); $key[3] = substr($key[0], 10, 5); $key[4] = substr($key[0], 15, 5); $key[5] = substr($key[0], 20, 5); return $key[1].'-'.$key[2].'-'.$key[3].'-'.$key[4].'-'.$key[5]; } public function getLicInfo($domain){ global $db, $config; $sql = "SELECT * FROM `licenses` WHERE `domain` = '{$domain}' LIMIT 1"; $result = $db->query($sql); if($result->num_rows == 1){ return $result->fetch_assoc(); } return false; } } $main = new Main; $domain = "".$_GET['domain'].""; $key = strtoupper($_GET['key']); if($lic = $main->getLicInfo($domain)){ if($lic['license_status']){ $twokey = $main->keygen($lic['license_domain']); if($twokey == $key){ $a = 'OK_'.$lic['license_domain']; } else { $a = 'ERROR_wrongkey'; } } else { $a = 'ERROR_nolicense'; } } else { $a = 'ERROR_nolicense'; } echo $a; exit(); ?>
Вот сам код api.php. Тут я хотел бы обратить ваше внимание на следующий код:
class Main { public function keygen($domain){ $key[0] = strtoupper(md5($domain)); $key[1] = substr($key[0], 0, 5); $key[2] = substr($key[0], 5, 5); $key[3] = substr($key[0], 10, 5); $key[4] = substr($key[0], 15, 5); $key[5] = substr($key[0], 20, 5); return $key[1].'-'.$key[2].'-'.$key[3].'-'.$key[4].'-'.$key[5]; }
Данный класс создает ключ домена путем использования md5 хэш.
2.Проверка доменного имена на наличие в базе данных
В 1 пункте мы с вами обозревали код api.php, который отвечает за работу скрипта. Хочу выделить код, который я уже выделял:
public function getLicInfo($domain){ global $db, $config; $sql = "SELECT * FROM `licenses` WHERE `domain` = '{$domain}' LIMIT 1"; $result = $db->query($sql); if($result->num_rows == 1){ return $result->fetch_assoc(); } return false; } }
Данный класс проверяет доменное имя на наличие в базе данных, и если все удачно, то скрипт работает; если нет, то он переадресует на основной сайт.
Вот мы с вами закончили обозревать код api.php, который отвечает за основную работу проверки лицензии, но теперь стоит вопрос: «А как его реализовать в самом скрипте?»
Делается оно благодаря следующему коду:
public function __destruct() { $request = file_get_contents("http://domain.com/api.php?domain=". $_SERVER['HTTP_HOST'] ."&key=".$this->config->lic_key); $status = explode("_", $request); if($status[0] != "OK" && "".$_SERVER['HTTP_HOST']."" != $status[1]){ header("Location: http://domain.com/"); } }
Этот код отправляет запрос в API и если имеется в базе данных, и если доменное имя есть в базе данных, то скрипт работает, если нет, то не работает. Такая же ситуация, если код неправильный, для этого в api.php существует следующий «отрезок» кода:
if($lic = $main->getLicInfo($domain)){ if($lic['license_status']){ $twokey = $main->keygen($lic['license_domain']); if($twokey == $key){ $a = 'OK_'.$lic['license_domain']; } else { $a = 'ERROR_wrongkey'; } } else { $a = 'ERROR_nolicense'; } } else { $a = 'ERROR_nolicense'; } echo $a; exit();
Думаю, тут понятно: если все правильно, то «выходит» сообщение ok_myssite.com и это удовлетворяет, то скрипт продолжает работу, а если введен неверный ключ или доменное имя, то «выходит» следующие сообщения (смотря где есть ошибка):
ERROR_nolicense
или же
ERROR_wrongkey
Думаю, все. Также жду конструктивных комментариев, и благодарю pixxxel за его статью «Защита PHP скриптов от копирования — это возможно?»
ссылка на оригинал статьи http://habrahabr.ru/post/263075/
Добавить комментарий