Подтвердить что ты не робот

Учитывая ключ сеанса и секрет, как мы можем расшифровать файлы cookie Rails?

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

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

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

И это в config/environment/production.rb и др.:

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

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

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

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

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

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

Джо

4b9b3361

Ответ 1

Если вы вытащите поле 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 (спасибо Chuck Vose)

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

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

Ответ 2

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. Исходный код находится в каталоге ваших драгоценных камней (/usr/lib/ruby/gems/1.8/gems в моей системе) в activesupport-2.3.5/lib/active_support/message_verifier.rb.

Ответ 3

Здесь, как расшифровать файл 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/handling-rails-4-sessions-with-go/

Ответ 4

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

ActionController::Base.session_store = EncryptedCookieStore

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

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

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

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

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

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

Ответ 5

Я написал камень Ruby для обработки файлов 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

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