Немного о компьютере

Шифрование файлов php. Увлекательная криптография или изыскания на тему обратимого шифрования на PHP. Функции шифрования в PHP

Все программные продукты для защиты 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. Большего внимания не заслуживает и практического интереса не представляет.

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

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

Отчасти потому, что это интересно, отчасти потому, что моделируя что-то свое и сравнивая это с признанными стандартами, наглядно видишь контраст, эффективные решения и откровенные упущения, понимаешь, к чему можно стремиться для повышения эффективности.

Но довольно уже воды.

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

Итак, напишем собственную систему обратимого шифрования с приватным и публичным ключом, такую, которая будет обладать следующими признаками мало мальски защищенного криптографического алгоритма:

  1. Наличие шумовых символов в итоговом шифре.
  2. Информация в каждом канале Отправитель-Адресат будет шифроваться по приватному ключу, причем функция соответствия будет уникальной для каждого ключа.
  3. Каждое сообщение будет получать дайджест-код - некий уникальный код, являющийся функцией от приватного ключа и исходного сообщения. Это требуется для того, чтобы добиться уникальности функции соответствия «исходный символ <=> закодированный символ» не только для канала «Отправитель-Адресат», но и для каждого отдельного сообщения.

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

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

Собственно говоря, итоговый результат посмотреть можно

Класс SymCoder включает в себя методы шифрования и дешифрования.

Шифрование осуществляет метод code(), принимающий на входе исходное сообщение.

Здесь сообщение по сгенерированной таблице соответствия в tab_coded создает зашифрованное сообщение, разбавленное по краям и внутри шумовыми символами.

Шумовые символы кстати уникальны для каждого канала отправитель-адресат, так как генерируются используя ключ канала, но не уникальны для сообщений. Используемые для шифрования символы в code_symbols представляют собой некоторые знаки пунктуации и символы вида %, @ и т.п.

На каждый кодируемый символ приходится два символа из code_symbols по понятным причинам, что их в несколько раз меньше, чем кодируемых символов.

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

К примеру, сообщение «привет, мир» будучи закодированным, выглядит вот так:

Digest-a00bf11d-&?==&!&?.@.@=!=-.?&1.#&?=:.:.1%!&-%@&@%~&1^#=?%%.!%+.?.~=?..&?%&&:%~.#%@&1&1.#=?.#.?.!&1==&=.-=!

А вот то же самое сообщение, закодированное снова:

Digest-a00bf11d-=:.?=:&!.?.1&-=:=?.?.=.?.!&=%!=-%@=!%~.=^#.1%%.!%+=:.~.@..==%&&1%~.1%@=?.@.!&=.!&@=:&1.==:=!.1&:

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

Сообщения обладают избыточностью, которая уменьшается по мере роста объема сообщения, в пределе доходя до 10% шума (для самых коротких сообщений шум достигает 90% и выше процентов), минимальная длина шифрованного сообщения - 116 символов. Один из некоторых минусов данного способа шифрования - увеличения кодированных сообщений как минимум в два раза.

Декодирование заключается в обратном переводе вида «кодовый символ» - исходный символ с вырезанием шума из сообщения. Что может быть в качестве ключа? В принципе, любая строка, уникальная для каждой пары вида адресат-получатель.

К примеру, если вы создаете мессенджер с шифрованием сообщений, в таком случае простейший вариант закрытого ключа может быть md5($user_id_1. $salt. $user_id_2), тогда ключ будет уникальный для каждого канала сообщений.

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

В качестве еще одного примера псевдошифрования приведу пример «шифрования» паролей в базе данных одной 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 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" ;
}
?>

Любую информацию можно как зашифровывать, так и расшифровывать, в том числе и с помощью 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 файл или БД, а получать с помощью дешифровки с ключем.

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

Похожие публикации