Шифрування даних на PHP

19

Від автора: у даному уроці ми з Вами розглянемо шифрування даних стандартними засобами мови PHP. Так як при створенні різних сценаріїв дуже часто виникає завдання шифрування даних. Наприклад, важливу інформацію, яку необхідно зберегти в куках, можна зашифрувати для підвищення безпеки сайту.

Шифрування даних на PHPШифрування даних на PHP

Введення

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

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

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

Так як шифрування даних – це ціла наука і при створенні власного алгоритму, Ви можете не врахувати безліч різних моментів. Що призведе до уразливості зашифрованих даних і можливо до злому їх зловмисниками. Краще всього використовувати вже готові алгоритми, які дуже надійні і, так сказати, перевірені часом. Алгоритм шифрування – це власне те, яким чином будуть зашифровані дані.

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

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

Шифрування даних на PHP

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

Шифрування даних на PHP

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

Шифрування даних на PHP

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

Шифрування даних

Для початку давайте створимо невелику форму для введення тексту, підлягає шифруванню:

Як Ви бачите – це звичайна форма і в браузері вона відображається ось так:

Шифрування даних на PHP

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

ВАЖЛИВО!!! Якщо цей ключ буде втрачено, то дані розшифрувати Ви вже не зможете!!!

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

$key = «GDSHG4385743HGSDHdkfgjdfk4653475jsghdjsdskjdf476354»;
$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 і подивимося що у нас вийшло:

Шифрування даних на PHP

Як Ви бачите все успішно працює — ми зашифрували дані, тепер нам належить їх розшифрувати.

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

Отже, у нас з Вами є зашифрований рядок, в якій спочатку йде вектор ініціалізації, а потім власне рядок з даними, яку нам потрібно отримати. Тому, нам необхідно заново відкрити модуль 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 «
«.$text;

Давайте в текстове поле введемо все ту ж рядок «hello world» і подивимося на результат:

Шифрування даних на PHP

Як Ви бачите все успішно працює. На всяк випадок приведу повний текст скрипта: