I think many people have come across the fact that sometimes it is necessary to protect your script from being copied, and you used different Ioncube, PHPLockit, but many people find it inconvenient to encode each time. I understand that in Ioncube there is such a thing, thanks to which it is possible to generate security keys, etc., but it is not profitable for many to buy or use someone else’s services, but it is not enough, everything happens.
Some people do not want to encode all the code, but only part of it, and for this many use this “array” to protect:
$_SERVER['HTTP_HOST']
But it's easy to get around:
')
$_SERVER['HTTP_HOST']=' ';
Therefore, there is a solution to this problem, and it can be solved by anyone with an initial knowledge of PHP, MySQL.
As a result, we get:
- The script will be encoded by obfuscator, which sends an API request to the site, where the API searches for the domain name and key in the database; if it is, the script will work; if not, it will redirect to the main site (the example would be: domain.com/api.php?domain=mysite1.ru&key=4024B-C0876-4FF0C-9A298-80EFA);
- We will also have a script api.php, which will be responsible for the operation of license verification, etc .;
- I also want to highlight the license key that we will receive. The license key is the md5 hash of the domain, which will be verified via api, and only the domain and its status will be recorded in the database.
Decision
1. Issuing licenses and checking the validity of the script via 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(); ?>
Here is the code itself api.php. Here I would like to draw your attention to the following code:
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]; }
This class creates a domain key by using the md5 hash.
2. Checking domain names for availability in the databaseIn paragraph 1, we reviewed the code api.php, which is responsible for the script. I want to highlight the code that I have already allocated:
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; } }
This class checks the domain name for availability in the database, and if everything is successful, the script works; if not, it will redirect to the main site.
So, we’ve finished reviewing the api.php code, which is responsible for the main work of checking the license, but now the question is: “How to implement it in the script itself?”
It is done thanks to the following code:
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/"); } }
This code sends a request to the API and if it exists in the database, and if the domain name is in the database, the script works, if not, it does not work. The same situation, if the code is wrong, for this in api.php there is the following "segment" of code:
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();
I think it’s clear here: if everything is correct, the message “ok_myssite.com“ comes out ”and it satisfies, the script continues to work, and if the wrong key or domain name is entered, then the following messages come out (depending on where there is an error):
ERROR_nolicense
or
ERROR_wrongkey
I think everything. I
am also waiting for constructive comments, and I thank
pixxxel for his article
“Protecting PHP scripts from being copied - is this possible?”