Учитывая ключ и секрет сеанса, как мы можем расшифровать куки Rails? - PullRequest
20 голосов
/ 21 декабря 2009

У меня вопрос о том, как Rails обрабатывает cookie шифрования / дешифрования.

У меня есть это в моем config / environment.rb

  config.action_controller.session = {
    :session_key => [some key],
    :secret => [some secret]
  }

И это в config / environment / production.rb et al. :

  ActionController::Base.session_options[:session_domain] = [some
domain]

Пока все хорошо - пока все мои приложения на Rails имеют одинаковые session_key и secret, и находятся в одном домене, все они могут использовать это же печенье.

Однако у коллеги теперь есть приложение JSP (в том же домене), с которой он хотел бы прочитать печенье, которое я установил.

Итак, учитывая секрет и зашифрованное значение cookie, как бы мы расшифровали чтобы получить содержимое этого куки?

(Документы, кажется, указывают, что это одностороннее шифрование SHA1 по умолчанию - http://caboo.se/doc/classes/CGI/Session/CookieStore.html - но тогда как мои Rails-приложения будут читать содержимое куки? это одностороннее шифрование?)

Заранее благодарим за любые советы / указатели / понимание,

Джо

Ответы [ 5 ]

17 голосов
/ 11 февраля 2010

Если вы извлекаете поле session.data прямо из данных сеанса, хранящихся в базе данных вашего приложения (если вы используете active_record_store в файле environment.rb)

config.action_controller.session_store = :active_record_store

... вот как вы его декодируете и возвращаете хеш:

Marshal.load(ActiveSupport::Base64.decode64(@session.data))

... или в Rails> = 3.2 (спасибо Чаку Возе)

Marshal.load(Base64.decode64(@session.data))

Он вообще не зашифрован.

12 голосов
/ 21 декабря 2009

Rails использует HMAC-SHA1 для шифрования данных cookie, что отличается от одностороннего шифрования SHA1, как вы и предполагали (см. статью в Википедии о HMAC для объяснения). Шифрование выполняется классом ActiveSupport::MessageVerifier (исходный код достаточно читабелен). Вот пример, основанный на тестовом приложении Rails:

secret = 'b6ff5a9c3c97bf89afe9a72e6667bafe855390e8570d46e16e9760f6394' +
  '4ab05577b211ec2f43f6c970441518f0241775499bde055078f754c33b62f68ba27ca'

cookie = "_test_session=BAh7CCIYdXNlcl9jcmVkZW50aWFsc19pZGkGIhV1c2VyX2NyZW" +
  "RlbnRpYWxzIgGAMzBlODkxZDQ2MWZhNjFkMDFmNzczMmJjNDdjMjIwZGFjMTY2NWEwNDMwZ" +
  "DVjMmUxOWY5MDFjMjQ5NWQ4OTM1OGZlMzE3NzRiZTFiZjM1ZTVlZDY2ZGUzYTkwOWZjZTgw" +
  "NTFlNGUxZWI0MTUzYTRjODZiMGZmMzM3NzliM2U3YzI6D3Nlc3Npb25faWQiJTgxNzk0Yjd" +
  "kN2IxYzRjMDE0M2QwOTk5NTVjZjUwZTVm--25c8f3222ab1be9f2394e2795a9f2557b06d0a92"

session = cookie.split('=').last
verifier = ActiveSupport::MessageVerifier.new(secret, 'SHA1')
verifier.verify(session)

Это должно вернуть ожидаемый хеш сессии. Чтобы реализовать это в Java, вашему коллеге придется дублировать метод ActiveSupport::MessageVerifier#verify. Исходный код находится в вашем каталоге gems (/usr/lib/ruby/gems/1.8/gems в моей системе) по адресу activesupport-2.3.5/lib/active_support/message_verifier.rb.

9 голосов
/ 14 марта 2014

Вот как расшифровать cookie сессии в Rails 4

def decrypt_session_cookie(cookie)
  cookie = CGI.unescape(cookie)
  config = Rails.application.config

  encrypted_cookie_salt = config.action_dispatch.encrypted_cookie_salt               # "encrypted cookie" by default
  encrypted_signed_cookie_salt = config.action_dispatch.encrypted_signed_cookie_salt # "signed encrypted cookie" by default

  key_generator = ActiveSupport::KeyGenerator.new(config.secret_key_base, iterations: 1000)
  secret = key_generator.generate_key(encrypted_cookie_salt)
  sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt)

  encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret)
  encryptor.decrypt_and_verify(cookie)
end

http://big -elephants.com / 2014-01 / обработки рельсов-4-сессия-с ходом /

8 голосов
/ 11 ноября 2011

По умолчанию Rails (до версии 4) не шифрует сеансовые куки, а только подписывает их. Чтобы зашифровать их, вам нужно сделать что-то вроде этого:

ActionController::Base.session_store = EncryptedCookieStore

Существует несколько плагинов, которые обеспечивают такую ​​функциональность шифрования.

Итак, если вы не используете специально зашифрованное хранилище, все, что нужно Java-коду, это проверить подпись cookie и декодировать cookie. Как говорит Алекс в своем ответе, вам нужно будет продублировать функциональность ActiveSupport::MessageVerifier#verify и поделиться ключом с приложением Java. Это и проверяет, и декодирует куки.

Если вы не хотите проверять подпись (которую я НЕ рекомендую), вы можете использовать метод декодирования Midwire из Base64 для просмотра хеша сессии. В Ruby это:

Marshal.load(ActiveSupport::Base64.decode64(the_cookie_value))

Я знаю, что это старо, но надеюсь, что это кому-нибудь поможет!

(Обновление: вопрос относится к Rails 3. Начиная с Rails 4, сессионные куки-файлы шифруются по умолчанию.)

1 голос
/ 13 июля 2016

Я написал Ruby gem для обработки файлов cookie, управляемых приложениями Rails. Прочитав его источник, вы сможете понять, как он работает, и, возможно, перенести его на Java, чтобы ваше приложение JSP могло использовать это:

https://github.com/rosenfeld/rails_compatible_cookies_utils

Это один файл с ~ 150 строками кода, который также обрабатывает только подписанные значения cookie и заботится как о подписании / шифровании, так и проверке / дешифровании, в то время как вы, похоже, беспокоитесь только о расшифровке. Это метод расшифровки:

https://github.com/rosenfeld/rails_compatible_cookies_utils/blob/master/lib/rails_compatible_cookies_utils.rb#L41-L52

Стоит отметить, что помимо ключа и секрета вам также необходимо знать, какой сериализатор используется. Раньше это был Marshal, но, похоже, по умолчанию для вновь создаваемых приложений теперь JSON. Если использовать Marshal, то может быть сложно преобразовать этот код в Java, поскольку вам нужно будет найти библиотеку, которая реализует Ruby Marshal # load.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...