Это старая редакция страницы Разработки / Движок / Gnu P G за 04/04/2007 20:49.
Общая спецификация интеграции GnuPG [ЧЕРНОВИК]
Задачи
Задачами, решаемыми интеграцией GnuPG, являются:
- Валидация загружаемого пользователем (в свой профиль) открытого ключа на корректность с последующим внесением отпечатка в базу данных.
- Защита приватной связи между пользователями сайта.
- Защита отправляемого пользователю восстановленного пароля.
- Функциональное обеспечение публичного доступа к серверам ключей.
- Функциональное обеспечение публичного декодировщика OpenPGP-пакетов.
Возможность аутентификации на сайте с помощью протокола запрос-ответ (подписание пользователем строки запроса, сгенерированной сервером) не определяется в числе задач, поскольку, хотя и скрывает пароль от наблюдателя на канале связи, сама по себе не в силах предотвратить несанкционированный доступ к учетной записи пользователя с помощью перехваченных cookie и иными путями. Решение же данной проблемы — SSL — вообще делает подобную схему избыточной, поскольку защищает как реквизиты авторизованной сессии (cookie/SID) при работе с сайтом, так и реквизиты пользователя (логин/пароль) в момент аутентификации.
Тем не менее, список задач остается открыт для дополнений.
Функции
Для решения означенных задач требуется реализовать следующий набор функций (достаточность и необходимость всех функций из списка подлежит обсуждению).
Загрузка/валидация ключа
Загрузка ключа выполняется на странице персональных настроек уже после регистрации и успешного входа в систему. Загрузка на этапе регистрации не имеет смысла по той причине, что HTTP-POST-запрос как целое не подвергается цифровому подписанию, и потому может быть модифицирован злоумышленником, тогда как использование SSL снимает подобные риски и на этапе регистрации, и последующего логина и изменения настроек.
Все этапы загрузки/валидации ключа выполняются в контексте специальной временной связки. Если импортированный ключ удовлетворяет необходимым условиям (см. ниже), производится его автоматический перенос в основную связку сервера.
UploadPK(keyASCII)
Импортирует загруженный ключ на временную связку. Единственный аргумент, keyASCII, представляет собой загруженный пользователем блок открытого ключа, передаваемый в GnuPG через STDIN с параметром --import. Сразу после исполнения вызывается CheckPK(keyID), которая анализирует ключ с целью определения его пригодности для зашифрования.
RecievePK(keyID[, ksURL])
Импортирует ключ с сервера ключей на временную связку. Передает GnuPG указанный пользователем (в профиле) ID ключа в параметре командной строки --recv-keys. Опциональный аргумент ksURL позволяет пользователю задать URL сервера ключей, вместо дефолтного subkeys.pgp.net. Как и в предыдущем случае сразу после исполнения вызывается CheckPK(keyID).
Вопросы: следует ли перед исполнением команды с параметром --recv-keys исполнить ее с --search-keys и, если сервер вернет более одно ключа, остановить программу и выдать предупрждение (к примеру, чтобы пользователь скорректировал запрос и указал keyID в 16-значном формате)? Альтернативным способом снятия двусмысленности может быть такой: показать пользователю результаты поиска и предложить выбрать принадлежащий ему ключ. Требуется протестировать альфу и изучить статус-коды, возвращаемые в различных описанных режимах.
AcceptPK(keyID)
Вызывается при импорте ключа в случае положительного ответа CheckPK() и переносит импортированный ключ с временной связки на главную. Использование идентификатора ключа в аргументе функции делает невозможным перенос нескольких ключей на главную связку, даже если пользователь и попытается это сделать (фактически будет импортирован только первый ключ в блоке).
<...>
Функции обслуживания
CheckPK(keyID)
Парсит сертификат ключа (используются параметры --with-colons --list-public-keys <keyID>) и проверяет следующие условия: 1) ключ содержит по крайней мере один шифровальный подключ и 2) базовый ключ и шифровальный подключ в данный момент действительны. Оба условия не имеют критического значения при загрузке ключа (пользователю выводится только предупреждение), но при восстановлении пароля или отправке зашифрованного приватного сообщения должно привести к неудачному завершению операции.
DeletePK(keyID)
Удаляет открытый ключ с главной связки, например, при необходимости заменить ключ или при удалении учетной записи пользователя из системы.
<...>
Реализация
Ограничивающим фактором в реализации схемы выступает запрет стандартной PHP-функции exec() (что является нормой для любого виртуального хостинга). Таким образом, взаимодействие с GnuPG может осуществляться только через интерфейс CGI. Использовать с этой целью CGI-сборку PHP нерационально, поэтому итоговая конструкция представляет собой:
. openSpace Engine
пользовательский уровень, графический интерфейс
/\
||
\/
openSpace-GPG engine class
функциональная прокладка, реализующая необходимый
набор функций ввода/вывода для взаимодействия с
GnuPG и проверки результатов операций
/\
||
\/
openSpace-GPG CGI wrapper
простейшая Perl-оболочка, "тупо" вызывающая GnuPG
с переданными параметрами командной строки и воз-
вращающая вывод программы верхнему уровню
/\
||
\/
GnuPG executable
исполняемый файл программы, лежащий за пределами
публичной www-директории сервера
Класс openSpace-GPG
Файл конфигурации gpg.conf
Поскольку GnuPG должен работать в полностью автономном режиме, видится необходимым следующий конфигурационный файл (корректировки?):
CGI-обертка openSpace-GPG
Идея использования пайпа для передачи данных GnuPG из стандартного ввода принадлежит ПэГусеву, за что ему особая благодарность. В остальном обертка не содержит ничего существенного: