Шифрование данных на PHP

Шифрование данных на PHP

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

скачать исходникискачать урок

Введение

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

Шифрование бывает двух видов: однонаправленное – когда данные можно только зашифровать, а расшифровать нельзя (к примеру, шифрование md5) и двунаправленное – когда есть возможность, как зашифровать, так и расшифровать данные. В данном уроке мы будем использовать двунаправленное шифрование. Для работы с шифрованием в языке PHP разработано расширение под названием mcrypt, которое позволяет шифровать данные используя различные алгоритмы шифрования (шифры).

Хочу сразу сказать ,что не стоит самому придумывать свой алгоритм шифрования!!!

Так как шифрование данных – это целая наука и при создании собственного алгоритма, Вы можете не учесть множество различных моментов. Что приведет к уязвимости зашифрованных данных и возможно к взлому их злоумышленниками. Лучше всего использовать уже готовые алгоритмы, которые очень надежны и, так сказать, проверены временем. Алгоритм шифрования – это собственно то, каким образом будут зашифрованы данные.

Каждый алгоритм поддерживает различные режимы шифрования. Режим шифрование – это метод применения блочного шифра, который позволяет преобразовать последовательность блоков исходного текста, который шифруется, в последовательность блоков зашифрованных данных. При этом при шифровании могут использоваться данные других блоков. Мы с Вами будем использовать один из лучших режимов шифрования — MCRYPT_MODE_CFB. Данный режим, еще называют режимом обратной связи по шифрованному тексту, т.е — это такой вариант использования блочного шифра, при котором для зашифровки следующего блока текста используется результат зашифровки предыдущего блока.

Полную документацию, по расширению mcrypt можно посмотреть на официальном сайте интерпретатора языка PHP, по адресу: http://us3.php.net/manual/ru/book.mcrypt.php

Полный перечень всех алгоритмов шифрования можно посмотреть по следующей ссылке: http://us3.php.net/manual/ru/mcrypt.ciphers.php

Ну и конечно все режимы шифрования доступны здесь: http://us3.php.net/manual/ru/mcrypt.constants.php

Теперь давайте приступим к шифрованию данных.

Шифрование данных

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

<form method="post">
<input type="text" name="str">

<input type="submit" value="Ok">
</form>

Как Вы видите – это обычная форма и в браузере она отображается вот так:

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

ВАЖНО!!! Если данный ключ будет утерян, то данные расшифровать Вы уже не сможете!!!

Данный ключ можно хранить в конфигурационном файле, главное, что бы к нему, кроме Вас, ни кто не имел доступа. Так как у нас нет конфигурационного фала, то я создам данный ключ внутри файла index.php:

$key = "GDSHG4385743HGSDHdkfgjdfk4653475JSGHDJSDSKJDF476354";

Обратите внимание – это обычная строка с произвольным набором символов. Вы вправе изменить ее по своему усмотрению. Итак, если пришли данные при помощи метода POST, значит, создаем переменную $str и сохраним в нее значение ячейки данного массива.

$str = $_POST['str'];

Далее необходимо открыть модуль mcrypt:

//открываем модуль шифрования и получаем его дискриптор
	$td = mcrypt_module_open(MCRYPT_BLOWFISH,'',MCRYPT_MODE_CFB,'');

Для этого применяем функцию mcrypt_module_open, которая открываем модуль mcrypt, для начала процесса шифрования. Параметры передаваемые функции:

MCRYPT_BLOWFISH – алгоритм шифра;

» — если алгоритм не стандартный, то в этом параметре указываем путь к алгоритму шифрования;

MCRYPT_MODE_CFB – режим шифрования;

» — если режим шифрования не стандартный, то в этом параметре указываем путь к режиму шифрования.

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

//  получаем размер вектора шифрования на основе дискриптора.
$iv_size = mcrypt_enc_get_iv_size($td);

Как Вы видите для определения длины вектора инициализации, используется функция mcrypt_enc_get_iv_size(), параметром которой необходимо передать дискриптор открытого модуля mcrypt. Теперь, необходимо создать данный вектор:

// Создание вектора шифрования
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

Функция mcrypt_create_iv(), создает вектор инициализации. Параметры, которые необходимо передать: $iv_size – длина вектора, MCRYPT_RAND – режим получения вектора инициализации, в нашем случае это генерация вектора случайным образом. Далее для начала шифрования данных, необходимо открыть буфер обмена:

// открытие буфера обмена, для шифровки данных
mcrypt_generic_init($td,$key,$iv);

Функция mcrypt_generic_init() – открывает буфер обмена, который необходим для процесса шифрования. Параметрами необходимо передать следующие значения:

$td – дискриптор открытого модуля mcrypt;

$key – секретный ключ, который необходим как для зашифровки данных, так и для их расшифровки;

$iv – вектор инициализации.

Теперь можно зашифровать данные:

//  шифруем даные
$crypt_text = mcrypt_generic($td,$str);

Для этого используем функцию mcrypt_generic(), которая собственно и шифрует данные, по выбранному алгоритму и режиму шифрования. Параметрами передаем следующие значения: $td – дискриптор открытого модуля mcrypt; $str – строка, которую необходимо зашифровать. И не забываем закрыть открытый буфер обмена и модуль mcrypt:

//  закрываем буфер обмена
mcrypt_generic_deinit($td);
mcrypt_module_close($td);

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

echo base64_encode($iv.$crypt_text);

Теперь давайте введем в текстовую форму строку hello world и посмотрим что у нас получилось:

Как Вы видите все успешно работает — мы зашифровали данные, теперь нам предстоит их расшифровать.

Расшифровка данных

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

$td = mcrypt_module_open(MCRYPT_BLOWFISH,'',MCRYPT_MODE_CFB,'');
$iv_size1 = mcrypt_enc_get_iv_size($td);

Как Вы видите, функции мы используем те же, с теми же параметрами. Далее из зашифрованной строки необходимо отделить вектор инициализации и саму строку с данными. Для этого мы с Вами используем размер вектора инициализации и обычную функцию substr(). Итак, получаем вектор инициализации:

$iv1 = substr($iv.$crypt_text,0,$iv_size1);

Как Вы видите, просто вырезаем часть строки, от нуля, до значения переменной $iv_size1 (длина вектора инициализации). Затем получаем строку с данными:

$crypt_text1 = substr($iv.$crypt_text,$iv_size1);

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

mcrypt_generic_init($td,$key,$iv1);

B вызываем функцию расшифровки данных:

$text = mdecrypt_generic($td,$crypt_text1);

Данная функция расшифровывает данные. Параметрами необходимо передать следующие значения: $td – дискриптор открытого модуля; ,$crypt_text1 – строку с зашифрованными данными. Затем закрываем буфер обмена, открытый модуль mcrypt и выводим результат на экран:

mcrypt_generic_deinit($td);
mcrypt_module_close($td);
echo "<br />".$text;

Давайте в текстовое поле введем все ту же строку “hello world” и посмотрим на результат:

Как Вы видите все успешно работает. На всякий случай приведу полный текст скрипта:

<?php
$key = "GDSHG4385743HGSDHdkfgjdfk4653475JSGHDJSDSKJDF476354";

if($_SERVER['REQUEST_METHOD'] == "POST") {
	$str = $_POST['str'];
	//открываем модуль шифрования и получаем его дискриптор
	$td = mcrypt_module_open(MCRYPT_BLOWFISH,'',MCRYPT_MODE_CFB,'');
	//  получаем размер вектора шифрования на основе дискриптора.
	$iv_size = mcrypt_enc_get_iv_size($td);
	// Создание вектора шифрования
	$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
	// открытие буфера обмена обмена для шифровки данных
	mcrypt_generic_init($td,$key,$iv);
	//  шифруем даные
	$crypt_text = mcrypt_generic($td,$str);
	//  закрываем буфер обмена и модуль
	mcrypt_generic_deinit($td);
	mcrypt_module_close($td);
	
	echo base64_encode($iv.$crypt_text);
	
	$td = mcrypt_module_open(MCRYPT_BLOWFISH,'',MCRYPT_MODE_CFB,'');
	$iv_size1 = mcrypt_enc_get_iv_size($td);
	$iv1 = substr($iv.$crypt_text,0,$iv_size1);
	$crypt_text1 = substr($iv.$crypt_text,$iv_size1);
	mcrypt_generic_init($td,$key,$iv1);
	$text = mdecrypt_generic($td,$crypt_text1);
	mcrypt_generic_deinit($td);
	mcrypt_module_close($td);
	
	echo "<br />".$text;	
}
?>
<form method="post">
<input type="text" name="str">

<input type="submit" value="Ok">
</form>

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

Фреймворк YII2: теория и первая практика

Овладейте азами фреймворка Yii2 за 5 дней!

Получить

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (11)

  1. Владимир

    Хочу обратиться к Вам как к специалисту. Подскажите пожалуйста, возможно ли создать скрипт который сможет основной текст заменить на текст с разбросанными словами, тем самым теряя суть и содержание информации ?

  2. Виктор Гавриленко

    Здравствуйте, Владимир!
    Я еще с данной задачей не сталкивался, но думаю это возможно. Другое дело, если Вам нужно будет как зашифровать текст (перемешать слова), так и потом расшифровать. Реализацию такого функционала, лучше поискать в готовом виде, так как я говорил в уроке. Шифрование данных — это целая наука и создать собственный алгоритм шифрования довольно сложно, да и можно не учесть все нюансы связанные с безопасностью.

  3. llaabbss

    Спасибо за статью.
    А можете еще выложить пример на php шифрования/дешифрования при помощи открытого и закрытого ключа получателя и подписью отправителя?

    • Виктор Гавриленко

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

  4. llaabbss

    Спасибо. Буду непременно ждать :)

  5. Юрий

    Дравствуйте очень интересный урок, интересует вопрос, Как расшифровать если допустим зашифрованные данные поместил в БД?

    • Виктор Гавриленко

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

  6. Александр

    Здравствуйте, Виктор! Спасибо за статью!
    Реализовал у себя на сайте кодировку строк. Строка кодируется успешно, а вот на выходе получаю абра кадабру, типа ‘ ���^���У���ڤ�̭�u@U.
    В чём может быть загвоздка? Подскажите пожалуйста!

    • Виктор Гавриленко

      Здравствуйте!
      Сложно вот так сказать — где то ошибка, нужно смотреть код.

      • Александр

        Я код скопировал точь в точь с исходников вашего урока. Передаю зашифрованную строку методом Ajax библиотеки JQ. На выходе получается отличная зашифрованная строка (вывожу её в консоль console.log(строка) ). Далее в контроллере получаю эту строку через POST , прохожу через 2 часть код из ваших исходников. В итоге получаю кракозябры. Причём при обновлении страницы, через F5 кракозябры постоянно разные.

        Пробовал шифровать так:

        Зашифровать строку
        $secretData = ‘Данные для шифрования’;
        $password = ‘Ключ шифрования’;
        $encDataBin = mcrypt_encrypt(MCRYPT_BLOWFISH, $password, $secretData, MCRYPT_MODE_ECB);
        $encDataStr = bin2hex($encDataBin);

        Расшифровать строку:
        $encDataBin = pack(«H*» , $encDataStr);
        $secretData = mcrypt_decrypt(MCRYPT_BLOWFISH, $password, $encDataBin, MCRYPT_MODE_ECB);

        То же самое — кракозябры на выходе. Может что-то нужно на сервере подправить или кодировку какую где поменять?

  7. Александр

    Вообщем решил вопрос методом JavaScript. На JS зашифровал нужную мне строку, а потом PHP функцией base64_decode() на сервере расшифровал строку.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree