3 мая 2015
4865
использование шифрования в PHP, шифрование, GPG

Использование шифрования в PHP

PHP

Использование шифрования в РНР достаточно сложная, но полезная задача, которая показывает применение шифрования, например, при отправке зашифрованной почты. Стандартом ранее был PGP - Pretty Good Privacy. Существуют бесплатные версии PGP, однако это программное обеспечение не является свободно распространяемым. Бесплатную версию можно применять только в некоммерческих целях.

 

Грубо говоря недавно появилась альтернатива PGP с открытым исходным кодом. GPG — Gnu Privacy Guard — представляет собой распространяемую свободно замену PGP. Он не содержит запатентованных алгоритмов и поэтому может использоваться в коммерческих целях без каких-либо ограничений. Как ни странно, но оба этих продукта выполняют свою задачу похожими способами, на уровне командной строки разница практически незаметна, но PGP имеет несколько полезных интерфейсов, например, модули для популярных почтовых программ, которые автоматически дешифруют сообщения при получении. GPG можно загрузить с сайта http://www.gnupg.org.

Приведу пример с использованием GPG для создания зашифрованных сообщений на Web-сервере. Возможно, GPG уже установлен у вас в системе, но если это не так, не стоит беспокоиться: процедура инсталляции проста, хотя настройка и требует некоторых ухищрений. Чтобы установить GPG на Linux машине, необходимо загрузить требуемый архивный файл из сайта www.gnupg.org, а затем воспользоваться утилитами gunzip и tar. Для компиляции и установки программы используются те же команды, что и для большинства программ Linux:

 

configure (или ./configure в зависимости от настроек систем)

make

make install

 

Если инсталляция производится не пользователем root, следует запустить конфигурационный сценарий с опцией --prefix:

 

./configure --prefiх=/путь/к/вашему/каталогу

 

Это требуется по той причине, что только пользователь root имеет права доступа к каталогу по умолчанию для GPG. Если все прошло хорошо, то GPG скомпилирован и выполняемый файл скопирован в /usr/local/bln/gpg или указанный каталог. Многие опции можно изменить — подробности приведены в документации по GPG. Кроме этого следует установить GPG или PGP и сгенерировать пару ключей в системе, с которой будет приходить почта. Стоит помнить, что пара ключей состоит из Открытого ключа (Public Key), который другие пользователи (и PHP-сценарии) применяют для шифрования почты до отправки, и Закрытого ключа (Private Key), который используется с вашей стороны для дешифрации полученных сообщений или шифрования исходящих. Важно, чтобы генерация ключа производилась на машине для чтения почты, а не на Web-сервере, так как закрытый ключ хранить на ней не следует. Если для генерации ключей вы используете версию командной строки GPG, следует ввести такую команду:

 

gpg --gen-key

 

Программа задаст несколько вопросов, причем на большинство из них можно дать ответ, предлагаемый по умолчанию. Программа запросит имя и почтовый адрес, которые будут использоваться в имени ключа. Ключ будет выглядеть к примеру так 'MY PASS'. Для экспорта общедоступного ключа из вновь созданной пары используется команда:

 

gpg --export > filename

 

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

 

gpg --export -a > filename

 

После извлечения открытого ключа файл можно загрузить на Web-сервер с использованием FTP.

 

Среди опций этой программы есть и help, которая выводит описание доступных команд — trust (доверять), sign (кодировать) и save (сохранить). Команда trust указывает GPG, что ключ достоин полного доверия, sign применяется для кодирования открытого ключа с использованием закрытого ключа пользователя nobody, save — для выхода из программы с сохранением всех изменений.

 

Тестирование GPG После всех этих операций пакет GPG настроен и готов к использованию. Для его тестирования потребуется создать файл test.txt, содержащий некоторый текст. Запуск команды

 

gpg –а --recipient 'MY PASS<my@post.gmail.com> --encrypt test.txt

(где задано имя вашего ключа) должен выдать предупреждение

 

gpg: Warning: using insecure memory! и создать файл с именем test.txt.asc. Он содержит зашифрованное сообщение, которое выглядит примерно так:

 

----- BEGIN PGP MESSAGE ----- Version: GnuPG vl . 0 . 3 (GNU/Linux)

Comment: For info see http://www.gnupg.org

hQEOAODU7hVGgdtnEAQAhr4HgR7xpIBsK9CiELQw85+klQdQ-bp/FzqL8tICrO.+B3OGJTEehPUDErwqUw/uQLTdsOrloPSrIAZ7c6G

VkhOYEVBj2MskT81IIBvdo95OyHPUCvg/rLxJlkxe4Vp8QFET5E3FdII/ly8VP5gSTE7gAgmOSbFf3S91PqwMyTkD2oJEvL6e3cP384s

Oi81rBbDbOUAAhCjjXt2DX/uX9q6P18QW56UICUOn4DPaWlG/gnNZCkcVDgLcKfBjbkB/TCTrohpA7o7kX4CIcIh7KlIMHY4RKdnCWQf

271oE+8i9cJRSCMsFIoI6MMNRCO.HY6p9bfxL2uE39IRJrQbe6xoEeOnkBOuTYxiLOTG+FrNrEtvBVMSOnsttu7HJey+oY4Z833pk5+

MeVwYumJwlvHjdZxZinV6wz46G02XGT17b28VwSBnWOoBHSZsPvkQXHTOq65EixP8y+YJvBN3z4pzdHOXa+NpqbH7q3+xXmd30

hDR +u7 t6MxTLDbgC+NR =gfQu END PGP MESSAGE

 

При переносе этого файла на систему, где был создан ключ, и запуске команды:

 

gpg -d test.txt.asc

можно просмотреть исходный текст сообщения.

Пример формы отправки сообщения и файлом обработки (шифрования):
 

<html>
<body>
<hl>Send Me Private Mail</hl>
<?
// Эту строку необходимо изменить, если не используются порты
// по умолчанию (порт 80 для обычного трафика и порт 443 для SSL)
if($HTTP_SERVER_VARS["SERVER_PORT"]!=443)
echo "<p><font color = red>
ВНИМАНИЕ! Вы не используете SSL. Ваше сообщение может быть доступно другим</font></p>";
?>
<form method=post action=send_private_mail.php><br>
Ваше мыло:<br>
<input type text name=from size=38><br>
Название:<br>
<input type=text name=title size=38><br>
Ваше сообщение:<br>
<textarea name=body cols=30 rows=10>
</textarea><br>
<input type=submit value="Отправить!">
</form>
</body>
</html>

 

Сам обработчик:

<?
$to_email = "your@localhost" ;

// Указазываем gpg, где находится набор ключей
// К примеру у меня в системе он содержится в каталоге /tmp/
putenv ( "GNUPGHOME=/ tmp/ . gnupg" ) ;

// Создаем уникальное имя файла
$infile = tempnam("", "pgp");
$outfile = $infile. " .asc" ;

// Записываем в файл текст, введенный пользователем
$fp = fopen($infile, "w");
fwrite($fp, $body) ;
fclose ($fp) ;

// Настраиваем параметры команды
$comnand = "/usr/local/bin/gpg -a \\
--recipient 'MY PASS<my@othersite.com>' \\
--encrypt -o $outfile $infile" ;

// Запускаем команду gpg
system ($ command, $result) ;

// Удаляем незашифрованный временный файл
unlink ($infile) ;
if ($result==0)
{
$fp = fopen($outfile, "r") ;
if (!$fp || filesize ($outfile) ==0)
{
$result = -1;
}
else
{

// Читаем зашифрованный файл
$contents = freed ($fp, filesize ($outfile) ) ;

// Удаляем временный зашифрованный файл
unlink <$outfile) ;
mail($to_email, $title, $contents, "From: $from\n") ;
echo "<h1>Отправка сообщения</h1>
<p>Ваше сообщение зашифровано и отправлено.</p>
<p>Спасибо.</p>" ;
if ($result!=0)
{
echo "<h1>Ошибка:</h1>
<p>Ваше сообщение не зашифровано и не отправлено.</p>
<p>Извините.</p>";} ?>