Эта статья - часть технической документации проекта PrivX. На сам проект мы давно положили болт, но изначально у нас была договоренность на этот случай - в случае провала описать наработки и идеи, которые у нас появятся в процессе, на тот день, когда кто-нибудь, с более высокой мотивацией, решит создать аналогичный проект. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// При проектировании любой приватки нужно решить две задачи: 1. Безопасный обмен данными; левые лица не должны узнать об содержимом передаваемых данных никаким способом. Эту задачу успешно решает криптография. Как пример, SSL или PGP. 2. Безопасное хранилище; левые лица не должны узнать о содержимом хранилища ни при каких обстоятельствах. Вот об этом мы и поговорим в данной статье. Для успешного восприятия материала, вы должны быть знакомы с RSA хотя-бы базово на пользовательском уровне (фактически, знания о назначении каждого типа ключа, закрытого и открытого, будет достаточно). Сначала рассмотрим пример - обычный закрытый форум, на распространенном движке типа vB, IPB, phpBB. Если настроить HTTPS, то, в принципе, первый пункт успешно решается. Но хранилище форума, в виде БД, имеет ряд недостатков: * Централизованность относительно местоположения. Если на сервере произойдет авария, или его арестуют, приватка будет недоступна. * Данные хранятся в незашифрованном виде. При взломе либо аресте сервера, данные могут быть извлечены из БД и прочитаны. Конечно можно сделать БД, хранимую только в памяти, но тогда при вынужденном ребуте либо перебое питания все содержимое базы пропадет. * Бэкапы базы нельзя хранить на непроверенных источниках. А проверенные, как легко догадаться, это жесткие диски самих участников. Что, конечно же, тоже небезопасно при аресте одного из участников. Система организации хранилища, описываемая в этой статье, лишена трех вышеперечисленных недостатков, поскольку использует в своей работе криптографию. Физически данные могут храниться в произвольном хранилище, даже на honeypot'е, хотя это и не рекомендуется. Итак, все пространство для данных разделяется на логические элементы - кластеры, в которых могут размещаться порции шифрованных данных, по аналогии с кластерами файловой системы на жестком диске. Естественно, раз имеет место разделение, необходимо также уметь и объединять части кластеров. Для этого нужно хранить базу индексов конкретных "виртуальных файлов". Группой доступа G будем называть объединение n пользователей {U1,U2,...,Un}. Основное предназначение группы доступа - контролировать доступ к данным для каждого пользователя. У каждой группы есть один или несколько координаторов. Задача координаторов - производить оперативную перегенерацию и обмен ключами. Каждая группа доступа имеет одну пару ключей RSA; наличие у члена группы закрытого ключа позволяет читать и (потенциально) писать данные. Наличие только открытого ключа не позволяет читать существующие данные, но позволяет записывать их в хранилище (сомнительная фича). Возможно открытый ключ группы можно выкладывать публично, с целью запросить инвайт в группу, или же оставить участникам свое резюме. Выкладывать закрытый ключ нельзя; во-первых, каждый кто его имеет, может прочитать зашифрованные данные, во-вторых, из закрытого ключа (n,d) гораздо легче получить открытый (n,e), поскольку модуль n - общий для обоих ключей, а открытая экспонента e как правило берется равной одному из чисел, расположенных в начале последовательности чисел Ферма. Значит, станет возможным не только читать, но и получить возможность модифицировать данные. Теперь сформируем требования к формату собственно зашифрованного пакета, хранимого на произвольных дисковых площадках. Обязательные поля, которые должны быть предусмотрены в пакете: *** Штамп времени формирования пакета. Необходим при синхронизации пакетов, а также для хронологии. Можно вполне использовать и UNIX timestamp. Основное требование к штампу - возможность восстановить из него дату/время хотя бы с отметкой. Поэтому хэши не подходят (это на случай если вы задумали взять sha-1 хэш от текущей даты и времени). *** Непосредственно сами данные, в незашифрованном виде. Хэш от незашифрованных данных. Нужен для проверки целостности сообщения после дешифровки пакета. Лучше не удалять это поле из спецификации, закон Мерфи и баги в реализациях RSA иногда дают о себе знать *** Уникальный идент автора и подпись данных его личным закрытым ключом. Это позволит определять автора сообщения, поста и т.д. Обратите внимание, что эта информация станет доступной только после дешифровки пакета. *** Соль для подписи автора. Её необходимо добавить к незашифрованному сообщению перед проверкой подписи. Необходима для защиты от атаки на подпись RSA в схеме с нотариусом. (Всякое бывает, лучше и предусмотреть). *** Энтропия. Это набор криптографически случайных данных. Обязательно использовать, когда шифруешь по RSA. Иначе злоумышленник может предположить содержимое пакета, и доказать свое предположение, имея ваш открытый ключ (который, как известно, публикуется). А то и вовсе восстановить ваш закрытый... Сам же пакет хранится на сервере вместе с его хэшем. Настоятельно не рекомендую дырявые алгоритмы вроде MD5. Используйте лучше MD6 или SHA-1, и следите за новостями в мире криптографии; главное - не пропустите появление квантовых компьютеров, потому что с их появлением алгоритм шифрования RSA станет легко вскрываем разложением числа n на множители и последующим восстановлением пары криптографических ключей. И все это недели, дни и часы, а не миллионы лет. Но думаю это еще не скоро будет. Рассмотрим теперь две операции, которые можно производить с группой доступа. ***Расширение доступа. Это предоставление новому участнику прав читать и писать в группу. Математически это преобразование {U1, U2, ..., Un} в {U1,U2, ..., Un, K}, где K - новый пользователь. На практике это означает сообщение ему пары ключей RSA, используемых группой. ***Сужение доступа. Если нужно лишить какого-нибудь участника прав на группу, необходимо сгенерировать новую пару ключей, перешифровать новым открытым ключом все данные, и сообщить новую пару ключей всем участникам, кроме исключаемого (одного или нескольких). Пожалуй, на этом все. ///////////////////////////////////////////////////////////////////////////////////////////////////
|