Написание зашифрованного хранилища файлов cookie для Rails; мой подход безопасен? - PullRequest
4 голосов
/ 18 июля 2009

По умолчанию Ruby on Rails сохраняет данные сеанса в файлах cookie. Это имеет много преимуществ, таких как отсутствие необходимости устанавливать какие-либо постоянные уровни на стороне сервера. Однако данные сеанса не зашифрованы, и приложение Rails, которое я пишу, помещает потенциально важные данные в сеанс. Я хотел бы избежать хранения данных сеанса на стороне сервера, если это возможно, и единственная существующая реализация хранилища зашифрованных файлов cookie для Rails, похоже, заброшена, поэтому я пишу свой собственный зашифрованный файл cookie.

Хранилище сеансов cookie Rails работает следующим образом:

  1. Сериализует данные сеанса в байтовую строку.
  2. Сериализованные данные преобразуются в base64.
  3. Данные base64 добавляются HMAC. Rails требует, чтобы секретный ключ HMAC был не менее 30 байтов; по умолчанию Rails генерирует 128-байтовую случайную строку в качестве секретного ключа, полученного из / dev / urandom. Алгоритм хеширования по умолчанию, используемый для HMAC, - SHA-1.
  4. Данные base64 + HMAC отправляются клиенту HTTP в виде файла cookie.
  5. Когда клиент выполняет запрос, Rails сначала проверяет, успешно ли прошла проверка HMAC. Если нет, то он молча отбрасывает данные сеанса в куки, как если бы пользователь вообще не отправлял данные сеанса. Это также означает, что если администратор изменяет секретный ключ HMAC, все старые сеансы автоматически становятся недействительными.
  6. Данные base64 выводятся из базы base64 и разбиваются на структуры данных Ruby.

Зашифрованное хранилище сеансов cookie, которое я пишу, подклассы обычного класса хранилища cookie. Он работает следующим образом:

  • Вставляет шаг 3.5: после шага 3 он шифрует данные.
  • Изменяет шаг 5: перед проверкой HMAC дешифрует данные.
  • Алгоритм шифрования - AES-256 в режиме CFB. Я понимаю, что EBC будет выставлять повторяющиеся шаблоны.
  • Код требует от администратора указать ключ шифрования ровно 32 байта. Ключ шифрования не хешируется. По умолчанию он предлагает случайно сгенерированный ключ шифрования ровно 32 байта, полученный из /dev/urandom.
  • Также требуется, чтобы администратор указал вектор инициализации ровно 16 байтов. IV не хэшируется, и по умолчанию он предлагает случайно сгенерированный IV, полученный из /dev/urandom.

Причина, по которой я HMAC перед шифрованием (вместо HMAC после шифрования), заключается в том, что я хочу иметь возможность обнаруживать изменения в ключе шифрования или в IV. Я хочу, чтобы программное обеспечение автоматически аннулировало старые сессии, если ключ шифрования или IV был изменен. Если у меня HMAC после шифрования, тогда проверка HMAC пройдет, если я изменю ключ шифрования или IV, что нежелательно.

Безопасен ли мой подход? Если нет, то чего не хватает?

Несколько заметок:

  • Я хочу использовать CTR, как рекомендовано http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html,, но, к сожалению, OpenSSL (который входит в стандартную библиотеку Ruby) не поддерживает CTR, и я не хочу, чтобы мои пользователи устанавливали отдельные сторонние крипто библиотеки.
  • Я хочу использовать SHA-256 для HMAC. daemonology.net рекомендует против SHA-512 из-за возможных «атак по побочным каналам на 32-битные системы» (что бы это ни значило). Однако SHA-256 как алгоритм хеширования для HMAC поддерживается не на каждой платформе. В частности, Ruby, поставляемый в OS X, не поддерживает HMAC + SHA256. Я хочу, чтобы мой код работал из коробки на OS X.

Ответы [ 3 ]

1 голос
/ 23 июля 2009

OpenSSL не нуждается в отдельном режиме CTR. Для реализации режима CTR вы сохраняете счетчик размера блока и шифруете этот счетчик в режиме ECB. Затем вы XOR зашифрованный счетчик с блоком открытого текста и увеличить счетчик. Дешифрование - это тот же процесс (поэтому cookie должен содержать начальное значение счетчика). Вы не должны никогда повторно использовать одно и то же значение счетчика с одним и тем же ключом, поэтому убедитесь, что счетчик только сброшен при изменении ключа.

1 голос
/ 18 июля 2009

Я не уверен, что читаю вас правильно на 100%, но если да, вы, похоже, упускаете смысл использования IV. Похоже, вы планируете иметь секретный IV, который вы будете использовать для каждого куки.

Нет необходимости в секретности капельниц. Кроме того, вы никогда не должны повторно использовать один и тот же IV с одним и тем же ключом.

Кроме этого, я не вижу существенных недостатков. Что не означает, что они не существуют.

0 голосов
/ 18 июля 2009

Как уже указывал oggy, вы должны создать уникальный IV и добавить его в каждый файл cookie. Для создания уникального IV / dev / urandom недостаточно, поскольку возможно, что он сгенерирует один и тот же IV для двух отдельных файлов cookie.

Несмотря на то, что я не эксперт, я думаю, что один действительный метод для создания уникального IV - это шифрование счетчика, который увеличивается для каждого cookie, с ключом, который не совпадает с ключом, используемым для шифрования данных cookie. с.


Добавлено намного позже:

Есть еще одна причина, о которой я только подумал позже, почему не очень хорошая идея использовать / dev / (u) случайным образом исключительно для IV в сценарии, который описал OP. В man-странице random (4) говорится, что пользователи должны быть экономными в использовании / dev / urandom, иначе они могут ухудшить качество случайности для других пользователей устройства. Поскольку количество прочитанных данных пропорционально клиентским запросам, вы должны предположить, что в сценарии ОП в конечном итоге будет прочитано большое количество случайностей.

Генераторы ключей, вероятно, будут читать из / dev / random, что блокирует, но у других более законных пользователей этих устройств (больше интересующихся случайностью) их случайность будет ухудшена. Ну, блокировать генераторы ключей тоже не очень хорошо.

Итак, поскольку OP не хочет сильно зависеть от сторонних библиотек, он может повторно использовать функции шифрования AES, используя их в режиме счетчика, как я обрисовал выше (также в статье в Википедии под заголовок Проекты на основе криптографических примитивов .

...