Шифрование в PHP. Руководство по шифрованию данных на PHP Защиты на уровне сервера

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

Рассмотрим основные методы шифровки

base64 - позволяет шифровать и расшифровывать данные алгоритмом MIME base64. Он не использует ключей и его часто используют для скрытия ссылок в php.

Примеры:
//шифруем текст
$text = "Ссылка";
echo base64_encode($text); //Выдаст: PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==
//дешифровка
echo base64_decode("PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==");
?>

Как видно мы использовали сначала операцию base64_encode и получили шифр: PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg== , а затем подставили его в base64_decode и получили ссылку обратно.

md5 - позволяет хэшировать данные в одностороннем порядке. То есть в отличие от base64, вы уже не сможете их расшифровать обратно. Часто md5 используют для хранения паролей в БД, но в последнее время зашифрованную комбинацию md5 стало легко найти в таблицах по расшифровке, любезно предоставленную многими сайтами и алгоритмами. Поэтому для хранения паролей md5 лучше заменять на Blowfish алгоритмы.

Пример:

//шифруем текст
echo md5("комбинация");
?>

Шифрование по ключу

И последний пример шифровки/дешифровки, о котором я хотел рассказать использует ключ (как пароль). То есть в функцию шифрования вы передаете уникальный ключ, код шифруется вместе с ним. Для расшифровки вы должны предоставить функции зашифрованный код и ключ, который знаете только вы. Пример использования функций в самом низу кода.

function __encode($text, $key) {



$enc_text=base64_encode(mcrypt_generic ($td,$iv.$text));
mcrypt_generic_deinit ($td);
mcrypt_module_close ($td);
return $enc_text; } }
function strToHex($string) {
$hex="";
for ($i=0; $i < strlen($string); $i++) { $hex .= dechex(ord($string[$i])); }
return $hex; }
function __decode($text, $key) {
$td = mcrypt_module_open ("tripledes", "", "cfb", "");
$iv_size = mcrypt_enc_get_iv_size ($td);
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
if (mcrypt_generic_init ($td, $key, $iv) != -1) {
$decode_text = substr(mdecrypt_generic ($td, base64_decode($text)),$iv_size);
mcrypt_generic_deinit ($td);
mcrypt_module_close ($td);
return $decode_text; } }
function hexToStr($hex) {
$string="";
for ($i=0; $i < strlen($hex)-1; $i+=2) { $string .= chr(hexdec($hex[$i].$hex[$i+1])); }
return $string; }

$str = "Булочки, которые надо зашифровать!
По ключу";
$code = strToHex(__encode($str, "My#key-do-36-simvolov"));
echo "Зашифрованный код: ".$code."
";

$str = __decode(hexToStr($code), "My#key-do-36-simvolov");
echo "Расшифрованный код: ".$str."
";
?>

Шифровать можно с html содержимым. Длина ключа должна быть не более 36 символов.

Этот метод можно использовать для шифровки каких-то данных и их помещения в txt файл или БД, а получать с помощью дешифровки с ключем.

Конечно, любой код можно расшифровать/взломать и этот не исключение, поэтому используйте надежные методы шифрования.

  • Перевод
  • Tutorial

От переводчика: в процессе программирования никогда не забываю о том, что я опасно некомпетентен в криптографии , и всем советую исходить из этого тезиса (ну, может быть кроме вас и еще вон того крутого парня). Однако, так или иначе, в процессе работы возникают задачи, связанные с защитой данных, и их надо решать. Поэтому я предлагаю вашему вниманию перевод статьи финского разрабочика Timo H , которая показалась мне достаточно интересной и полезной.

Это краткое руководство о том, как избежать распространенных ошибок с симметричным шифрованием на PHP.

Будем рассматривать случай, когда данные обрабатываются на стороне сервера (в частности, шифрование происходит на сервере, а данные могут быть получены, например, от клиента в виде открытого текста, пароля и т.п.), что является типичным случаем для PHP-приложений.

Cведения из этого руководства не стоит использовать для создания шифрованных сетевых соединений, которые имеют более сложные требования. Для таких случаев надо использовать spiped или TLS .

Естественно, рекомендации, приведенные здесь, не являются «единственно возможным способом» организации шифрования на PHP. Цель этого руководства - попытаться оставить поменьше места для ошибок и сложных неоднозначных решений.

Функции шифрования в PHP

Используйте расширения Mcrypt или OpenSSL .

Алгоритм шифрования и его режим работы, одноразовый код (вектор инициализации)

Используйте AES-256 в режиме CTR со случайным одноразовым кодом (прим. перев.: nonce ). AES это стандарт, поэтому можно использовать функции любого из расширений - Mcrypt или OpenSSL.

Всегда генерируйте новый одноразовый код. При этом вы должны пользоватся криптографически стойким источником случайных чисел. Немного подробнее о генерации случайных чисел читайте ниже. Одноразовый код не является секретом, и может быть конкатенирован с шифротекстом для передачи и последущей расшифровки.

Одноразовый код должен быть длиной 128 бит (16 байт), просто строка байт без какого-либо кодирования.

В расширении Mcrypt AES известен как Rijndael-128 (прим. перев.: несмотря на то, что речь идет про AES-256, это не ошибка. AES-256 != Rijndael-256 ). В OpenSSL соответственно AES-256-CTR.

Пример использования Mcrypt:
Пример использования OpenSSL:
Убедитесь, что шифрование работает правильно с помощью тестовых векторов (прим. перев.: для AES-256-CTR см. пункт F.5.5 на странице 57 ).

Для режима CTR существуют некоторые ограничения на суммарный объем шифруемых данных. Возможно вы не встретитесь с этим на практике, но имейте ввиду, что не стоит шифровать более чем 2^64 байт данных одним ключом, безоносительно того одно ли это длинное сообщение или много коротких.

Режим CTR сохраняет стойкость только если не использовать один и тот же одноразовый код с одним и тем же ключом. По этой причине важно генерировать одноразовые коды при помощи криптографически стойкого источника случайности. Кроме того, это означает, что вы не должны шифровать более чем 2^64 сообщений с одним ключом. Поскольку длина одноразового кода 128 бит, важно ограничение на количество сообщений (и соответствующих им одноразовых кодов) 2^128/2 из-за парадокса Дней рождения (прим. перев.: ).

И помните, что шифрование не сможет скрыть тот факт, сколько данных вы посылаете. Как пример экстремального случая, если вы шифруете сообщения, содержащие только «да» или «нет», очевидно, шифрование не скроет эту информацию.

Аутентификация данных

Всегда проводите проверку подлинности и целостности данных.
Для этого после шифрования используйте MAC . Т.е. сначала данные шифруются, а затем берется HMAC-SHA-256 от полученного шифротекста, включая собственно шифротекст и одноразовый код.

При расшифровке сначала проверте HMAC, используя алгоритм сравнения устойчивый к атакам по времени. Не сравнивайте напрямую $user_submitted_mac и $calculated_mac, используя операторы сравнения == или ===. Лучше даже использовать "двойную проверку HMAC ".

Если проверка HMAC удачна, можно безопасно производить расшифровку. Если же HMAC не подходит, немедленно завершайте работу.

Ключи шифрования и аутентификации

В идеале использовать ключи, полученные из криптографически стойкого источника случайности. Для AES-256 необходимы 32 байта случайных данных («сырая» строка – последовательность бит без использования какой-либо кодировки).

Если приложение запущено под PHP версии ниже 5.5, где нет встроеной реализации PBKDF2, то придется использовать собственную реализацию на PHP, пример которой можно найти тут: https://defuse.ca/php-pbkdf2.htm . Имейте ввиду, что полагаясь на собственную реализацию, возможно не получится преобразовать ключ должным образом, как это делает встроенная функция hash_pbkdf2().

Не используйте один и тотже ключ для шифрования и аутентификации. Как сказано выше, необходимо 32 байта на ключ шифрования и 32 байта на ключ аутентификации (HMAC). С помощью PBKDF2 вы можете получить 64 байта из пароля и использовать, скажем, первые 32 байта в качестве ключа шифрования, и остальные 32 байта для ключа аутентификации.

Если у вас пароли хранятся в файле, например, в виде HEX-строки, не перекодируйте их перед тем как «скормить» функциям шифрования. Вместо этого используйте PBKDF2 для преобразования ключей из HEX-кодировки сразу в качественный ключ шифрования или аутентификации. Или используйте SHA-256 с выводом без дополнительного кодирования (просто строка в 32 байта) для хеширования паролей. Использование обычного хеширования паролей дает достаточно энтропии. Подробнее описано в следующих параграфах.

Растяжение ключа

Во-первых, следует избегать использования ключей с низкой энтропией. Но все же, если необходимо использовать, например, пользовательские пароли, то обязательно надо использовать PBKDF2 с большим числом итераций, чтоб максимизировать безопасность ключа.

Одним из параметров PBKDF2 является количество итераций хеширования. И чем оно выше, тем на большую безопасность ключа можно рассчитывать. Если ваш код работает на 64-битной платформе, используйте SHA-512 в качестве алгоритма хэширования для PBKDF2. В случае 32-битной платформы используйте SHA-256.

Однако, невозможно использовать относительно высокое количество итераций в онлайн-приложенях из-за риска DoS-атаки. Поэтому качество ключа не будет столь высоко, как в оффлайновых приложениях, которые могут позволить себе большое число итераций без такого риска. Как правило, для онлайн-приложений подбирают такое количество итераций хеширования, чтоб PBKDF2 отрабатывал не более 100 мс.

В случае, если вы можете использовать пароли с высокой энтропией, не обязательно проводить «растяжение», как для паролей с низкой энтропией. Например, если вы создаете «главный_ключ_шифрования» и «главный_ключ_аутентификации», используя /dev/urandom, то необходимость в PBKDF2 вообще отпадает. Только убедитесь, что используете ключи как последовательности бит, без какого-либо кодирования.

Кроме того, с помощью PBKDF2 несложно получить оба ключа и для шифрования, и для аутентификации от одного мастер-пароля (просто использовать небольшое количество итераций или даже одну). Это полезно, если у вас есть только один «мастер-пароль», используемый и для шифрования, и для аутентификации.

Хранение и управление ключами

Самое лучшее - это использовать отдельное специализированное устройство для хранения ключей (HSM).

Если это невозможно, то для усложнения атаки, можно использовать шифрование файла с ключами или файла конфигурации (в котором хранятся фактические ключи шифрования / аутентификации) с помощью ключа, хранящегося в отдельном месте (вне домашего каталога или корня сайта). Например, вы можете использовать переменную окружения Apache в httpd.conf, чтобы сохранить ключ, необходимый для расшифровки файла с фактическими ключами:
SetEnv keyfile_key crypto_strong_high_entropy_key # You can access this variable in PHP using $_SERVER["keyfile_key"] # Rest of the config
Теперь, если файлы в корне сайта и ниже, в том числе файлы с ключами, будут скомпрометированы (например, при утечке бэкапа), зашифрованные данные останутся в безопаности поскольку ключ, хранящийся в переменной окружения, не был скомпрометирован. Важно помнить, что файлы httpd.conf следует бэкапить отдельно, и не скомпрометировать переменную keyfile_key через, например, вывод phpinfo().

Если вместо параметра конфигурации вы используете файл, то возможно организовать ротацию ключей. В худшем случае, если противник заполучил ваши ключи шифрования и аутентификации, и этот факт остался незамеченным, то ротация ключей с какой-то периодичностью может ограничить его доступ (при условии, что он не может заполучить новые ключи). Такой прием поможет уменьшить ущерб, потому что противник не сможет использовать скомпрометированные ключи бесконечно.

Сжатие данных

В общем случае не стоит сжимать исходный текст до шифрования. Это может дать противнику дополнительный инструмент для анализа.

Например, если вы храните данные сессии в зашифрованных cookie, при этом некоторые из этих данных предоставлены пользователем, а некоторые представляют секретную информацию, противник может узнать дополнительную информацию о секрете, посылая как рядовой пользователь определенным образом сформированные данные и измеряя как меняется длина получаемых шифротекстов.

Текст сжимается более эффективно, если есть повторяющиеся участки. Манипулируя данными пользователя, можно подбирать так, чтоб они частично совпадали с секретными данными. Чем больше совпадение, тем меньший размер шифротекста будет на выходе. Такой тип атаки называется CRIME .

Если у вас нет жесткой необходимости сжимать данные, не сжимайте.

Серверное окружение

Как правило, не стоит размещать требовательные к безопасности приложения на разделяемом сервере. Например, на виртуальном хостинге, где противник может получить доступ к виртуалке на том же физическом сервере, что и вы.

Есть различные причины, делающие разделяемые сервера сомнительным местом для размещения критичных к безопасности приложений. Например, недавно были продемонстрированы атаки между виртуальными серверами: eprint.iacr.org/2014/248.pdf . Это хорошее напоминание, что техники нападения не деградируют, а наоборот оттачиваются и улучшаются со временем. Всегда надо учитывать такие подводные камни.

Консультация эксперта

И последнее, но не по важности, проконсультируйтесь с экспертом, пусть он сделает ревью вашего кода, отвечающего за безопасность.

(PHP 4, PHP 5, PHP 7)

crypt — One-way string hashing

Warning

This function is not (yet) binary safe!

Description

crypt (string $str [, string $salt ]) : string

crypt() will return a hashed string using the standard Unix DES -based algorithm or alternative algorithms that may be available on the system.

The salt parameter is optional. However, crypt() creates a weak hash without the salt . PHP 5.6 or later raise an E_NOTICE error without it. Make sure to specify a strong enough salt for better security.

password_hash() uses a strong hash, generates a strong salt, and applies proper rounds automatically. password_hash() is a simple crypt() wrapper and compatible with existing password hashes. Use of password_hash() is encouraged.

Some operating systems support more than one type of hash. In fact, sometimes the standard DES-based algorithm is replaced by an MD5-based algorithm. The hash type is triggered by the salt argument. Prior to 5.3, PHP would determine the available algorithms at install-time based on the system"s crypt(). If no salt is provided, PHP will auto-generate either a standard two character (DES) salt, or a twelve character (MD5), depending on the availability of MD5 crypt(). PHP sets a constant named CRYPT_SALT_LENGTH which indicates the longest valid salt allowed by the available hashes.

The standard DES-based crypt() returns the salt as the first two characters of the output. It also only uses the first eight characters of str , so longer strings that start with the same eight characters will generate the same result (when the same salt is used).

On systems where the crypt() function supports multiple hash types, the following constants are set to 0 or 1 depending on whether the given type is available:

  • CRYPT_STD_DES - Standard DES-based hash with a two character salt from the alphabet "./0-9A-Za-z". Using invalid characters in the salt will cause crypt() to fail.
  • CRYPT_EXT_DES - Extended DES-based hash. The "salt" is a 9-character string consisting of an underscore followed by 4 bytes of iteration count and 4 bytes of salt. These are encoded as printable characters, 6 bits per character, least significant character first. The values 0 to 63 are encoded as "./0-9A-Za-z". Using invalid characters in the salt will cause crypt() to fail.
  • CRYPT_MD5 - MD5 hashing with a twelve character salt starting with $1$
  • CRYPT_BLOWFISH - Blowfish hashing with a salt as follows: "$2a$", "$2x$" or "$2y$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z". Using characters outside of this range in the salt will cause crypt() to return a zero-length string. The two digit cost parameter is the base-2 logarithm of the iteration count for the underlying Blowfish-based hashing algorithmeter and must be in range 04-31, values outside this range will cause crypt() to fail. Versions of PHP before 5.3.7 only support "$2a$" as the salt prefix: PHP 5.3.7 introduced the new prefixes to fix a security weakness in the Blowfish implementation. Please refer to for full details of the security fix, but to summarise, developers targeting only PHP 5.3.7 and later should use "$2y$" in preference to "$2a$".
  • CRYPT_SHA256 - SHA-256 hash with a sixteen character salt prefixed with $5$. If the salt string starts with "rounds=
  • CRYPT_SHA512 - SHA-512 hash with a sixteen character salt prefixed with $6$. If the salt string starts with "rounds=$", the numeric value of N is used to indicate how many times the hashing loop should be executed, much like the cost parameter on Blowfish. The default number of rounds is 5000, there is a minimum of 1000 and a maximum of 999,999,999. Any selection of N outside this range will be truncated to the nearest limit.

As of PHP 5.3.0, PHP contains its own implementation and will use that if the system lacks of support for one or more of the algorithms.

Parameters

The string to be hashed.

Caution

Using the CRYPT_BLOWFISH algorithm, will result in the str parameter being truncated to a maximum length of 72 characters.

An optional salt string to base the hashing on. If not provided, the behaviour is defined by the algorithm implementation and can lead to unexpected results.

Return Values

Returns the hashed string or a string that is shorter than 13 characters and is guaranteed to differ from the salt on failure.

Warning

When validating passwords, a string comparison function that isn"t vulnerable to timing attacks should be used to compare the output of crypt() to the previously known hash. PHP 5.6 onwards provides hash_equals() for this purpose.

Changelog

Version Description
5.6.5 When the failure string "*0" is given as the salt , "*1" will now be returned for consistency with other crypt implementations. Prior to this version, PHP 5.6 would incorrectly return a DES hash.
5.6.0 Raise E_NOTICE security warning if salt is omitted.
5.5.21 When the failure string "*0" is given as the salt , "*1" will now be returned for consistency with other crypt implementations. Prior to this version, PHP 5.5 (and earlier branches) would incorrectly return a DES hash.
5.3.7 Added $2x$ and $2y$ Blowfish modes to deal with potential high-bit attacks.
5.3.2 Added SHA-256 and SHA-512 crypt based on Ulrich Drepper"s » implementation .
5.3.2 Fixed Blowfish behaviour on invalid rounds to return "failure" string ("*0" or "*1"), instead of falling back to DES.
5.3.0 PHP now contains its own implementation for the MD5 crypt, Standard DES, Extended DES and the Blowfish algorithms and will use that if the system lacks of support for one or more of the algorithms.

Examples

Example #1 crypt() examples

$hashed_password = crypt ("mypassword" ); // let the salt be automatically generated

/* You should pass the entire results of crypt() as the salt for comparing a
password, to avoid problems when different hashing algorithms are used. (As
it says above, standard DES-based password hashing uses a 2-character salt,
but MD5-based hashing uses 12.) */
if (hash_equals ($hashed_password , crypt ($user_input , $hashed_password ))) {
echo "Password verified!" ;
}
?>

Example #2 Using crypt() with htpasswd

// Set the password
$password = "mypassword" ;

// Get the hash, letting the salt be automatically generated
$hash = crypt ($password );
?>

Example #3 Using crypt() with different hash types

/* These salts are examples only, and should not be used verbatim in your code.
You should generate a distinct, correctly-formatted salt for each password.
*/
if (CRYPT_STD_DES == 1 ) {
echo "Standard DES: " . crypt ("rasmuslerdorf" , "rl" ) . "\n" ;
}

if (CRYPT_EXT_DES == 1 ) {
echo "Extended DES: " . crypt ("rasmuslerdorf" , "_J9..rasm" ) . "\n" ;
}

if (CRYPT_MD5 == 1 ) {
echo "MD5: " . crypt ("rasmuslerdorf" , "$1$rasmusle$" ) . "\n" ;
}

if (CRYPT_BLOWFISH == 1 ) {
echo "Blowfish: " . crypt ("rasmuslerdorf" , "$2a$07$usesomesillystringforsalt$" ) . "\n" ;
}

if (CRYPT_SHA256 == 1 ) {
echo "SHA-256: " . crypt ("rasmuslerdorf" , "$5$rounds=5000$usesomesillystringforsalt$" ) . "\n" ;
}

if (CRYPT_SHA512 == 1 ) {
echo "SHA-512: " . crypt ("rasmuslerdorf" , "$6$rounds=5000$usesomesillystringforsalt$" ) . "\n" ;
}
?>

Допустим, требуется обмен данными между двумя серверами. Чтобы обезопасить данные от прослушивания трафика, данные шифруются. Ну например, передача действий внутри ботнета. Вот , что по сути не является шифрованием, а называется кодированием и для раскодирования подобного кода применяются известные функции.

В качестве еще одного примера псевдошифрования приведу пример «шифрования» паролей в базе данных одной CMS – там пароли шифруются не в md5() или , а просто кодируются через base64. Т.е. при сливе базы хакеру не составит никого труда расшифровать все пароли через встроенную php-функцию base64_decode().

Нам же нужно передавать данные, не беспокоясь о том, что кто-то сможет перехватить текст и расшифровать его. В PHP есть популярный пакет шифрования данных Mcrypt, обеспечивающий возможность двустороннего шифрования (то есть собственно шифрование и расшифровку данных).

Mcrypt версии 2.4.7 поддерживает следующие алгоритмы симметричного шифрования: Blowfish, RC2, Safer-sk64 xtea, Cast-256, RC4, Safer-sk128, DES, RC4-iv, Serpent, Enigma, Rijndael-128, Threeway, Rijndael-192, TripleDES, LOKI97, Rijndael-256, Twofish, Panama, Saferplus и т.д. Подробнее про каждый алгоритм написано в Википедии.

Так как используется симметричное шифрование , то ключ должен быть известен обеим сторонам и храниться в секрете.

Пример шифрования и расшифровки строки

mcrypt_module_open("des", "", "ecb", "")
Эта функция открывает модуль алгоритма и используемый режим. Для данного примера Алгоритм DES в режиме ECB.

$key = substr($key, 0, mcrypt_enc_get_key_size($td));
Максимальный размер ключа должен быть получен вызовом функции mcrypt_enc_get_key_size(), и каждое значение меньше полученного будет правильным.

$s = mcrypt_generic($td, $source);
При шифровании данные заполняются нулевыми байтами, чтобы гарантировать длину данных в n*blocksize. Размер блока blocksize определяется алгоритмом (для DES размер блока 64 бита). Поэтому при расшифровке в конце строки могут появиться “\0”, которые удаляются функцией trim()

Все программные продукты для защиты PHP-скриптов подразделяются на две категории: требующие установки на сервер дополнительных модулей и работающие с обычной конфигурацией web-серверов. Первые более надежны в плане безопасности, так как переводят PHP-скрипты из текстового вида в специальный двоичный-код, но требуют доступа к серверу с правами администратора. Вторые могут работать практически на всех хостингах с поддержкой PHP, в том числе и бесплатных, но не представляют большой сложности для взлома. В отдельную подгруппу можно выделить исходного кода, не использующие шифрование или сжатие.

Защиты на уровне сервера:

Zend Encoder / Zend SafeGuard Suite - наиболее популярная коммерческая защита, модули для поддержки Zend обычно установлены на всех платных хостингах. Zend предоставляет привязку скриптов к доменам и ip, установку времени триальной работы скриптов и мощную обфускацию. Поддерживаются все операционные системы. В публичном доступе имеется несколько вариантов утилит для снятия Zend"а, все они представляют собой модифицированный PHP 4-й и 5-й версии. Старые версии Zend"а снимаются без проблем, в последних возникают сложности из-за обфускации исходного кода.

Новая, активно развивающаяся коммерческая защита. На уровне собственных API предоставляет взаимодействие с защищаемыми скриптами, поддерживаются операционные системы Windows и Linux. Вследствие малой распространенности не устанавливается на обычных виртуальных хостингах, но вполне может быть установлена пользователями на выделенных серверах. Публичных декодеров нет.

Коммерческая защита, практически не встречается, на вирутальных хостингах не устанавливается. Позволяет устаналивать триальный срок работы скриптов с проверкой даты по внешним серверам точного времени, делать привязку защищаемых скриптов к серверам, ip-адресу, MAC-адресу сетевой карты, причем эти данные используются для расшифровки. Поддерживаются все операционные системы. Публичных декодеров нет.

phpSHIELD . Прототип SourceGuardian for PHP. После слияния двух разработчиков перестал развиваться как самостоятельный продукт. Основной функционал тот же самый, публичных декодеров нет.

ionCube PHP Encoder . Второй по популярности коммерческий продукт для защиты скриптов. После появления публичных декодеров для Zend стал все чаще использоваться и устанавливаться на виртуальных хостингах. Позволяет шифровать не только скрипты, но и шаблоны, xml-документы, изображения, бинарные файлы. Привязывает защищенные файлы к серверам, есть мощный обфускатор, поддерживаются все операционные системы. Публичных декодеров нет, но в некоторых случаях снимается deZender"ом.

PHTML Encoder . Малораспространенная коммерческая система защиты, предоставляет обычный функционал для продуктов такого типа, работает под всеми операционными системами. За отдельную плату можно приобрести исходные коды защиты и модифицировать их под свои нужды. Публичных декодеров нет.

DWebEncoder . Экзотическая защита под Windows, предназначенная для создания скриптовых презентаций и каталогов на компакт-дисках. В установленном виде представляет собой что-то типа самостоятельного web-сервера, на котором исполняются закодированные php-скрипты. Публичных декодеров нет.

PHP Compact . Защита скорее теоретическая, чем практическая. Разрабатывалась на одном из отечественных форумов, но похоже дальше авторских релизов дело не продвинулось. Декодеров нет, впрочем как и защищенных скриптов.

Дополнение с открытым кодом к старинным php-акселераторам Turck MMCache и eAccelerator. Переводит скрипты в байт-код с целью повышения скорости их выполнения. Есть версии модулей под Windows и Linux. Публичных декодеров нет, но возможно открытый код проекта как-то поможет в изучении.

Защиты на уровне исходного кода:

PHP LockIt! . Популярная коммерческая защита, встречается очень часто, в основном на скриптах зарубежных разработчиков. Позволяет устанавливать триальный срок работы скриптов, привязку к доменам и ip-адресам, сжимает скрипты штатными средствами php (gzinflate). Единственная сложность - хороший обфускатор. Различные версии защиты отличаются только модификацией модуля распаковки. Легко снимается как в ручном, так и в автоматическом режиме. Без обфускатора снимается в точности до исходного кода, с обфускатором требует дополнительной обработки.

CNCrypto . В свободном доступе нет даже демо-версии, анализ проводился по защищенным скриптам. Навесной модуль сложности в распаковке не представляет, защита держится только на хорошей обфускации исходного кода.

PHPCipher . Защита представляет собой он-лайн сервис. На сайт загружается архив с вашими скриптами и обратно скачивается уже защищенный. Платная лицензия позволяет подписывать защищенные скрипты своими данными и использовать для коммерческих целей. Бесплатная лицензия допускает использование только для личных нужд. Сама защита представляет собой защищенный Zend"ом php-модуль, который подключается к защищенным скриптам. После deZend"а модуля защиты и получения из него всех необходимых констант снимается полностью до исходного кода. Функции обфускатора нет.

ByteRun Protector for PHP . Коммерческий продукт, в зависимости от типа лицензии позволяет защищать скрипты как на уровне сервера, так и на уровне исходного кода. Серверная защита со стандартными возможностями, ничего особенного нет. Защита на уровне скриптов снимается очень легко автоматически и вручную. Публичного декодера на серверную версию нет.

Очень популярная у отечественных разработчиков защита. Представляет собой сильно замусоренный пустым кодом модуль защиты, который подключается через include к защищенным скриптам. Алгоритм декодирования очень простой, не вызывает никаких сложностей в ручном и автоматическом снятии. Во всех случаях снимается полностью до исходного кода, функции обфускатора нет. Есть небольшие особенности для частных случаев декодирования, но здесь они описаны не будут.

CodeLock . Еще одна популярная защита, отличный пример безграмотного программирования. Представляет собой приложение на php, позволяет кодировать как сами скрипты, так и результат их работы в браузере средствами javascript. Скрипты можно защищать паролем, но из-за бездарной реализации пароль легко узнать даже не снимая навесную защиту. Модуль защиты представляет собой замусоренный пустым кодом php-скрипт, который подключается к защищаемым скриптам. Алгоритм защиты очень простой, снимается полностью до исходного кода. Функции обфускации нет.

TrueBug PHP Encoder , с недавнего времени TrueBug PHP Obfuscator & Encoder. Очень интересный протектор для исследования. До версии 1.0.2 использовались стандартные средства php для gzip-компрессии, начиная с версии 1.0.3 авторами был разработан собственный алгоритм сжатия. В новом продукте TrueBug PHP Obfuscator & Encoder добавлена функция обфускации и оптимизации исходного кода. Единственное слабое место защиты - неизменный алгоритм декодирования скриптов, но сам алгоритм меняется для каждой версии защиты. После разбора защиты снимается легко в точности до исходного кода, естественно при условии что не был использован обфускатор.

Zorex PHP CryptZ . Защита, как и CodeLock, представляет собой приложение на php, для его работы требуется база MySQL. Модуль защиты - подключаемый скрипт на php, зашифрованный в несколько слоев. После разбора алгоритма снимается очень легко в точности до исходного кода. Функции обфускатора нет.

Free PHP Encoder . Бесплатный он-лайновый сервис для кодирования php-скриптов. Модуль защиты представляет собой подключаемый php-скрипт, накрытый Zend"ом, который надо скачать с сайта. После снятия Zend"а и разбора алгоритма защита легко снимается полностью до исходного кода. Алгоритм защиты неизменный, функции обфускатора нет.

Скрипт на php, кодирование примитивное, стандартный base64. Большего внимания не заслуживает и практического интереса не представляет.