Шифрование Рассмотрим задачу шифрования сообщений и

advertisement
Шифрование
Рассмотрим задачу шифрования сообщений и файлов с помощью алгоритма XXTEA.
XXTEA — расширение шифроалгоритма XTEA, опубликованное в 1998 году. В нем
исправлена уязвимость в предшествующем алгоритме. Отличительной особенностью
алгоритма является также возможность зашифровки блоков любого кратного 32 битам
размера (минимальный размер 64 бита), в то время как другие алгоритмы данного
семейства TEA, XTEA, XTEA-3, Raiden и RTEA используют блоки фиксированного
размера, равного двум или четырем 32-х битным числам.
По определению википедии, Tiny Encryption Algorithm (TEA) — блочный алгоритм
шифрования типа «Сеть Фейстеля», представленный в 1994 году Дэвидом Уилером (David
Wheeler) и Роджером Нидхэмом (Roger Needham). У этого алгоритма в чистом виде были
найдены
уязвимости,
поэтому
у
него
существуют
две
усовершенствованные
модификации: XTEA и XXTEA (закрывает недостатки XTEA). XXTEA является
последней модификацией, поэтому мы будем использовать именно ее.
Длина ключа в XXTEA = 128 бит.
В представленном далее коде файла xxtea.inc.php (листинг 1) мы располагаем двумя
важными функциями: xxtea_encrypt и xxtea_decrypt. Остальные функции носят
вспомогательный характер.
Внимание! Этот файл xxtea.inc.php мы будем подключать к своим программам
этого раздела. Поэтому его текст надо скопировать из данного текстового документа в
блокнот и сохранить в своей папке www сайта под именем xxtea.inc.php.
Для работы после этого нам потребуется:
1. Подключать данный файл xxtea.inc.php в свои скрипты:
require_once 'xxtea.inc.php';
2. Шифровать информацию с указанием ключа:
$cipher = xxtea_encrypt('Важная информация', 'MyKluchPassword');
3. Дешифровать информацию с указанием ключа:
$info = xxtea_decrypt($cipher, 'MyKluchPassword');
В данном случае в переменной $info получаем: Важная информация.
Листинг 1. Файл xxtea.inc.php (набор функций для шифрования)
<?php
// набор функций для шифрования методом XXTEA
function long2str($v, $w) {
$len = count($v);
$n = ($len - 1) << 2;
if ($w) {
$m = $v[$len - 1];
if (($m < $n - 3) || ($m > $n)) return false;
$n = $m;
}
$s = array();
for ($i = 0; $i < $len; $i++) {
$s[$i] = pack("V", $v[$i]);
}
if ($w) {
return substr(join('', $s), 0, $n);
} else {
return join('', $s);
}
}
function str2long($s, $w) {
$v = unpack("V*", $s. str_repeat("\0", (4 - strlen($s) % 4) & 3));
$v = array_values($v);
if ($w) {
$v[count($v)] = strlen($s);
}
return $v;
}
function int32($n) {
while ($n >= 2147483648) $n -= 4294967296;
while ($n <= -2147483649) $n += 4294967296;
return (int)$n;
}
function xxtea_encrypt($str, $key) {
if ($str == "") {
return "";
}
$v = str2long($str, true);
$k = str2long($key, false);
if (count($k) < 4) {
for ($i = count($k); $i < 4; $i++) {
$k[$i] = 0;
}
}
$n = count($v) - 1;
$z = $v[$n];
$y = $v[0];
$delta = 0x9E3779B9;
$q = floor(6 + 52 / ($n + 1));
$sum = 0;
while (0 < $q--) {
$sum = int32($sum + $delta);
$e = $sum >> 2 & 3;
for ($p = 0; $p < $n; $p++) {
$y = $v[$p + 1];
$mx = int32((($z >> 5 & 0x07ffffff) ^ $y << 2) +
(($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ int32(($sum ^ $y) +
($k[$p & 3 ^ $e] ^ $z));
$z = $v[$p] = int32($v[$p] + $mx);
}
$y = $v[0];
$mx = int32((($z >> 5 & 0x07ffffff) ^ $y << 2) +
(($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ int32(($sum ^ $y) +
($k[$p & 3 ^ $e] ^ $z));
$z = $v[$n] = int32($v[$n] + $mx);
}
return long2str($v, false);
}
function xxtea_decrypt($str, $key) {
if ($str == "") {
return "";
}
$v = str2long($str, false);
$k = str2long($key, false);
if (count($k) < 4) {
for ($i = count($k); $i < 4; $i++) {
$k[$i] = 0;
}
}
$n = count($v) - 1;
$z = $v[$n];
$y = $v[0];
$delta = 0x9E3779B9;
$q = floor(6 + 52 / ($n + 1));
$sum = int32($q * $delta);
while ($sum != 0) {
$e = $sum >> 2 & 3;
for ($p = $n; $p > 0; $p--) {
$z = $v[$p - 1];
$mx = int32((($z >> 5 & 0x07ffffff) ^ $y << 2) +
(($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ int32(($sum ^ $y) +
($k[$p & 3 ^ $e] ^ $z));
$y = $v[$p] = int32($v[$p] - $mx);
}
$z = $v[$n];
$mx = int32((($z >> 5 & 0x07ffffff) ^ $y << 2) +
(($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ int32(($sum ^ $y) +
($k[$p & 3 ^ $e] ^ $z));
$y = $v[0] = int32($v[0] - $mx);
$sum = int32($sum - $delta);
}
return long2str($v, true);
}
?>
Стоит нам изменить ключ при расшифровке, при выводе мы не получим ничего, т.к.
ключ задан неверно. Длина ключа может быть не более 128 бит, т.е. 16 байт. Поэтому если
мы зададим в качестве второго аргумента функции xxtea_encrypt/xxtea_decrypt
значение длиной больше 16 байт, она примет во внимание только первые 16 байт.
Таким же образом с легкостью можно шифровать содержимое файла.
Секретный ключ всегда следует хранить отдельно от шифра, иначе весь смысл
шифрования конечно теряется. На то он и секретный, что его должен знать только тот, кто
зашифровал, чтобы впоследствии обратить шифр.
Перейдем к практической работе и как и в предыдущих примерах создадим для этого
новый сайт.
1. Пример шифрования текстового сообщения
Мы рассмотрим несколько примеров и листинг 2 содержит тестовый скрипт,
который позволяет зашифровать сообщение, а затем его расшифровать (рис. 1).
Листинг 2. Файл test_1.php
<?php
require_once 'xxtea.inc.php';
$key="лдоотевс5234389";
// Ключ - набор от 1-го до 16 символов
$soob="Это важная информация";
echo "<br><strong>Начальное сообщение</strong> ".$soob;
$cipher = xxtea_encrypt($soob,$key);
echo "<br><strong>Шифрованное сообщение</strong> ".$cipher;
$deshif= xxtea_decrypt($cipher, $key);
// Дешифрованное сообщение
echo "<br><strong>Дешифрованное сообщение</strong> ".$deshif;
?>
Рис. 1
Для удобства дальнейшей работы создадим как и ранее стартовую страницу сайта
index.html. Листинг 3 содержит текст файла index.html в первоначальном варианте,
а на рис. 2 показана эта страница в окне браузера. В этом случае мы располагаем только
одной гиперссылкой на выше рассмотренную программу.
Листинг 3. Файл index.html
<html>
<body>
<h3>Шифрование </h3>
<P><a href="test_1.php"> Шифрование и дешифрование текстового сообщения</a></P>
</body>
</html>
Рис. 2
1. Шифрование сообщений в базе данных
Рассмотрим следующую задачу. Один человек отправляет на сайт сообщения,
которые зашифровывает определенным ключом. Другой человек эти сообщения
расшифровывает, при условии, что он знает ключ. В результате на сайте сообщения
хранятся в зашшифрованном виде и недоступны для просмотра.
В базе данных сформируем таблицу tn_soob (рис.3). В данной таблице мы будем
фиксировать шифрованные сообщения на сайте.
Итак, в таблице tn_soob будут присутствовать следующие поля:

id — тип int, ключевое поле (необходимо установить автоинкремент);

a — тип varchar (500 символов), предназначено для хранения шифрованного
сообщения;
Рис. 3
Создадим теперь файл soob_form.html (листинг 4), который будет содержать
форму для отправки сообщения на сайт и ввода ключа для шифрования сообщения. Сама
данная форма в окне браузера показана на рис. 4.
Листинг 4. Файл soob_form.html
<FORM
method="POST" ACTION = "soob_obr.php" >
<P>Введите ключ (строка от 1-го до 16) символов:
<INPUT type = "text" name = "key" value=""></P>
<P>
Введите сообщение:
<INPUT type = "text" name = "soob" value=""></P>
<INPUT TYPE ="submit" name="new_soob" value="OK">
</FORM>
Рис. 4
Для обработки формы soob_form.html нам понадобится скрипт soob_obr.php (листинг 5),
который будет фиксировать введенное сообщение в базе данных.
Листинг 5. Файл soob_obr.php
<?php
require_once('connected.php');
if (isset($_POST['new_soob'] ))
{
require_once 'xxtea.inc.php';
$key=$_POST['key'];
$soob=$_POST['soob'];
$cipher = xxtea_encrypt($soob,$key);
$sql="INSERT INTO t1_soob SET a='".$cipher."'";
mysql_query($sql);
echo "Новое сообщение внесено";
}
?>
Скорректируем файл
index.html
(листинг 5).
Листинг 5. Файл index.html
<html>
<body>
<h3>Шифрование </h3>
<P><a href="test_1.php"> Шифрование
текстового сообщения</a></P>
<P><a href="soob_form.html"> Отправка сообщения на сайт</a></P>
</body>
</html>
Таким образом, у нас имеется механизм формирования шифрованных сообщений в базе данных.
3. Дешифрование сообщений в базе данных
Создадим файл soob_form_deshifr.html (листинг 6), который будет содержать форму для
ввода ключа и дешифрации имеющихся сообщений в базе данных. Сама форма в окне
браузера показана на рис. 5.
Листинг 6. Файл soob_form_deshifr.html
<FORM
method="POST" ACTION = "deshifr.php" >
<P>Введите ключ (строка от 1-го до 16) символов:
<INPUT type = "text" name = "key" value=""></P>
<P>
<INPUT TYPE ="submit" name="new_soob" value="OK">
</FORM>
Рис. 5
Для обработки информации от формы на рис. 5 создадим скрипт
Результат работы данного скрипта показан на рис. 6.
Листинг 7. Файл deshifr.php
<?php
deshifr.php
(листинг 7).
require_once('connected.php');
$sql="SELECT * FROM t1_soob";
$result=mysql_query($sql);
$key=$_POST['key'];
require_once 'xxtea.inc.php';
echo "<TABLE border=1>";
echo "<TR><TD>Номер</TD><TD>Шифрованное сообщение</TD>
<TD>Дешифрованное сообщение</TD>
</TR>";
$i=1;
while ($line=mysql_fetch_row($result))
{
$soob=$line[1];
$cipher =
xxtea_decrypt($soob, $key);
echo "<TR><TD>".$i."</TD>";
echo "<TD>".$soob."</TD>";
echo "<TD>".$cipher."</TD></TR>";
$i=$i+1;
}
echo "</TABLE>";
?>
Рис. 6
Скорректируем файл
index.html
(листинг 8).
Листинг 8. Файл index.html
<html>
<body>
<h3>Шифрование </h3>
<P><a href="test_1.php"> Шифрование и дешифрование текстового сообщения</a></P>
<P><a href="soob_form.html"> Отправка сообщения на сайт</a></P>
<P><a href="soob_form_deshifr.html"> Форма для отправки ключа при дешифрировании
сообщений</a></P>
</body>
</html>
4. Шифрование файлов
Рассмотрим теперь шифрование файлов. Во-первых, на стартовой странице добавим
новую гиперссылку:
<a href="files_form.html"> Форма для отправки файла</a>
В результате стартовая страница будет выглядеть так, как показано на рис. 7.
Рис. 7
По гиперссылке Форма
для
отправки
файла будет открываться форма,
показанная на рис. 8, а сам текст программного кода приведен в листинге 9.
Листинг 9. Файл files_form.html
<FORM
method="POST"
enctype="multipart/form-data" ACTION = "file_obr.php" >
<P>Введите ключ (строка от 1-го до 16) символов:
<INPUT type = "text" name = "key" value=""></P>
<P>
Укажите файл:
<INPUT type = "file" size=100 name = "filename"></P>
<INPUT TYPE ="submit" name="new_file" value="OK">
</FORM>
Рис. 8
Скрипт file_obr.php для обработки информации от данной формы показан в листинге 10.
Листинг 10. Файл file_obr.php
<?php
require_once('connected.php');
if (isset($_POST['new_file'] ))
{
$key=$_POST['key'];
require_once 'xxtea.inc.php';
if ( copy($_FILES["filename"]["tmp_name"],
$_FILES["filename"]["name"]))
{
echo ("Файл загружен");
$fd=fopen($_FILES["filename"]["name"],"r");
$b=fread($fd,filesize($_FILES["filename"]["name"]));
fclose($fd);
echo ($b);
echo ("<HR>");
$cipher = xxtea_encrypt($b, $key);
echo ($cipher);
echo ("<HR>");
$fd2=fopen($_FILES["filename"]["name"],"w");
fwrite($fd2,$cipher);
fclose($fd2);
$vih=xxtea_decrypt($cipher, $key);
$fd3=fopen($_FILES["filename"]["name"],"w");
fwrite($fd3,$vih);
fclose($fd3);
echo ($vih);
}
else
echo ("Файл не загружен");
}
?>
В результате на следующей странице (рис. 9) мы увидим:
 информацию,имеющуюся в файле;
 закодированную информацию;
декодированную информацию.

Рис. 9
5. Шифрование файлов в базе данных
Рассмотрим теперь полноценный пример, в котором файлы, загруженные на сайт
будут шифроваться и фиксироваться в базе данных. Другой пользователь при наличии
пароля может эти файлы вернуть в первоначальный вид и извлечь.
Скорректируем файл
index.html
(листинг 11). А именно добавим в него две новые
гиперссылки (в тексте листинга выделены жирным шрифтом).
Листинг 11. Файл index.html
<html>
<body>
<h3>Шифрование </h3>
<P><a href="test_1.php"> Шифрование и дешифрование текстового сообщения</a></P>
<P><a href="soob_form.html"> Отправка сообщения на сайт</a></P>
<P><a
href="soob_form_deshifr.html">
Форма
для
оправки
при
дешифрировании
сообщений</a></P>
<P><a href="files_form.html"> Форма для отправки файла</a></P>
<P><a href="files_baza_form.html"> Форма для отправки файла в базу данных</a></P>
<P><a href="files_baza_out.php"> Форма для извлечения файла из базы данных</a></P>
</body>
</html>
В нашей базе данных создадим таблицу name_files (рис. 10).
Итак, в таблице name_files будут присутствовать следующие поля:

id — тип int, ключевое поле (необходимо установить автоинкремент);

n — тип varchar (100 символов), предназначено для хранения имени файла.
Рис. 10.
Листинг 12 содержит текст формы Форма для отправки файла в базу данных.
Листинг 12. Файл files_baza_form.html
<FORM
method="POST"
enctype="multipart/form-data" ACTION = "file_baza_obr.php" >
<P>Введите ключ (строка от 1-го до 16) символов:
<INPUT type = "text" name = "key" value=""></P>
<P>
Укажите файл:
<INPUT type = "file" size=50 name = "filename"></P>
<INPUT TYPE ="submit" name="new_file" value="OK">
</FORM>
Скрипт
file_baza_obr.php,
который
обрабатывает
форму
files_baza_form.html
приводится в листинге 13. В результате файл пользователя загружается на сайт,
фиксируется в базе данных и после этого шифруется.
Листинг 13. Файл file_baza_obr.php
<?php
require_once('connected.php');
if (isset($_POST['new_file'] ))
{
$key=$_POST['key'];
require_once 'xxtea.inc.php';
if ( copy($_FILES["filename"]["tmp_name"],
$_FILES["filename"]["name"]))
{
echo ("Файл загружен");
$fd=fopen($_FILES["filename"]["name"],"r");
$b=fread($fd,filesize($_FILES["filename"]["name"]));
fclose($fd);
$cipher = xxtea_encrypt($b, $key);
$fd2=fopen($_FILES["filename"]["name"],"w");
fwrite($fd2,$cipher);
fclose($fd2);
$f=$_FILES["filename"]["name"];
$sql="INSERT INTO t1_name_files
SET n='".$f."'";
mysql_query($sql);
}
else
echo ("Файл не загружен");
}
?>
После загрузки нескольких файлов на рис. 11 показана информация в таблице name_files.
Рис. 11.
Перейдем теперь к гиперссылке:
<P><a href="files_baza_out.php"> Форма для извлечения файла из базы данных</a></P>
Сама форма, которая открывается на экране показана на рис. 12.
Листинг 14. Файл files_baza_out.php
<?php
require_once('connected.php');
$sql="SELECT * FROM t1_name_files ORDER BY n";
$result=mysql_query($sql);
?>
<P> Выберите файл в списке: </P>
<form method="post" action="obr_files_baza.php">
<select
name="spisok">
<?php
while ($line=mysql_fetch_row($result))
{
echo "<option value=".$line[1].">$line[1]";
}
?>
</select>
<br><br><br>
Ключ : <input type='text' name='pas'>
<br><br><br>
<input name='ent' type='submit' value='ОК'>
</form>
<P><a href="index.html"> Вернуться на стартовую страницу </a><br><P>
Рис. 12.
Здесь мы должны выбрать файл и указать ключ для его расшифровки (рис. 13).
Рис. 13.
После этого на экране открывается гиперссылка (рис. 14). щелчком по которой уже можно
сохранить, а затем открыть файл с дешифрованным содержимым.
Рис. 14.
Download