Шифрування в PHP. Зашифрувати, розшифрувати дані по ключу в PHP Ключі шифрування та автентифікації

  • Переклад
  • Tutorial

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

Це короткий посібник про те, як уникнути поширених помилок із симетричним шифруванням на PHP.

Розглянемо випадок, коли дані обробляються на стороні сервера (зокрема, шифрування відбувається на сервері, а дані можуть бути отримані, наприклад, від клієнта у вигляді відкритого тексту, пароля тощо), що є типовим випадком для PHP-додатків .

Відомості з цього посібника не варто використовувати для створення шифрованих мережевих з'єднань, які мають більш складні вимоги. Для таких випадків треба використовувати 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 # Ви можете використовувати цей параметр в PHP за допомогою $_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

Ця функція не (Yet) binary safe!

Description

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

crypt() will return a hashed string using the standard Unix DES -базується algorithm or alternative algorithms that may be available on the system.

Salt parameter is optional. However, crypt() creates a weak hash without salt . PHP 5.6 або короткий випадок E_NOTICE error без нього. Make sure to specify сильний приємний salt for better security.

password_hash()використовує сильний шапку, генерує сильний солод, і applies property rounds автоматично. password_hash() is a simple crypt()завантажувати і спроможний з наявним password hashes. Use of password_hash() is encouraged.

Кілька операційних систем support more than one type of hash. У fact, деякісвідомості стандарту DES-based algorithm is replaced by MD5-based algorithm. Hash type is triggered by the salt argument. Пріор до 5.3, PHP буде визначати наявні algoritmy на встановленому-часі, заснованому на системі" crypt(). Якщо не буде реалізовано, PHP буде автоматично генерувати її стандартний два character (DES) salt, або twelve character ( MD5), залежно від наявності MD5 crypt() PHP sets a constant named CRYPT_SALT_LENGTH which indicates the longest valid salt дозволяється за наявними hashes.

The standard DES-based crypt() returns the salt as the first 2 characters of the output. Це також тільки використовує перші вісім characters of str , так багато strings, що start with the same eight characters will generate the same result (when the same salt is used).

На системах, де crypt() функція supports multi hash types, following constants є set to 0 or 1 depending on whether given type available:

  • CRYPT_STD_DES- Standard DES-based hash with 2 character salt from the alfabet "./0-9A-Za-z". Використовуючи неправильні характеристики в salt will cause crypt() to fail.
  • CRYPT_EXT_DES- Extended DES-based hash. "Салт" є 9-character string, що включає в себе підшипник, що випливає з 4 байт з iteration count і 4 байт з salt. Ці є зображені як printable characters, 6 bits per character, least significant character first. Ціни 0 до 63 є вказані "./0-9A-Za-z". Використовуючи неправильні характеристики в salt will cause crypt() to fail.
  • CRYPT_MD5- MD5 hashing with a twelve character salt starting with $1$
  • CRYPT_BLOWFISH- Blowfish hashing with salt as follows: "$2a$", "$2x$" або "$2y$", два digits cost parameter, "$", і 22 characters from aphabet "./0-9A- Za-z". Використовуючи параметри з цього рівня в salt буде викликати crypt(), щоб відновити 0-length string. У двох категоріях вартості параметрів є основа 2 логотипом iteration count для підзаводу Blowfish-оснований наповнення algorithmeter і мусить бути в межах 04-31, значення поза цим рівнем буде викликати crypt() до нескінченності. Versions of PHP до 5.3.7 тільки підтримують "$2a$" як salt prefix: PHP 5.3.7 встановлює нові prefixes до fix a security weakness in Blowfish implementation. Подивіться на повні details of 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= $", numerical value of N is used to indicate how man times the hashing loop should be executed, might like the cost parameter on Blowfish. Будь-який вибір N поза межами цього розміру буде розрахований на найближчий термін.

Як PHP 5.3.0, PHP містить його власну реалізацію і буде використовувати те, що якщо система щитів підтримує одну або більше конкретних algoritms.

Parameters

The string to be hashed.

Caution

За допомогою CRYPT_BLOWFISH algorithm, буде результат в str parameter, коли trunced to a maximum length of 72 characters.

На опційний salt string на базі hashing on. Якщо не передбачено, ця зміна визначається як algoritm implementation і може бути спрямована на невідповідні результати.

Return Values

Поверніть нарізані string або string, що є шорти, що мають 13 characters і є гарантованим до різного від сала на байдужі.

Warning

Коли validating passwords, string comparison function that isn"t vulnerable to timing attacks should be used to compare the output of crypt()до попереднього славного hash. PHP 5.6 onwards provides hash_equals() for this purpose.

Changelog

Version Description
5.6.5 Якщо помилка string "*0" є загальним як гроза , "*1" буде нібито відновлено для координації з іншими crypt implementations. Пріор до цієї версії, PHP 5.6 буде incorrectly return a DES hash.
5.6.0 Raise E_NOTICE Захист warning і якщо salt is omitted.
5.5.21 Якщо помилка string "*0" є загальним як гроза , "*1" буде нібито відновлено для координації з іншими crypt implementations. Пріор до цієї версії, PHP 5.5 (і earlier branches) буде 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 і SHA-512 crypt заснований на Ulrich Drepper"s » implementation .
5.3.2 Знижений Blowfish behaviour on invalid rounds return "failure" string ("*0" or "*1"), позбавляючись falling back to DES.
5.3.0 PHP зараз містить його власну implementation для MD5 crypt, Standard DES, Extended DES і Blowfish algoritms і буде використовувати те, що якщо система щитів підтримує один або більше algoritms.

Examples

Example #1 crypt() examples

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

/* Ви повинні 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,
але MD5-базований 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

/* Ці salts є examples only, and should not be used verbatim in your code.
Ви повинні генерувати, відрізняти, правильно-форматований salt для кожного 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 або БД, а отримувати за допомогою дешифрування з ключем.

Звичайно, будь-який код можна розшифрувати/зламати і це не виняток, тому використовуйте надійні методи шифрування.

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

З очевидних причин не замахуватимемося на гігантів індустріальної криптографії на кшталт 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, Rijn 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. Розмір блоку блокусиза визначається алгоритмом (для DES розмір блоку 64 біта). Тому при розшифровці наприкінці рядка можуть з'явитися “\0”, які видаляються функцією trim()