Given the session key and secret, how can we decrypt Rails cookies?
我有一个关于Rails如何处理cookie的问题加密/解密。
我的config/environment.rb中有这个。
1 2 3 4 | config.action_controller.session = { :session_key => [some key], :secret => [some secret] } |
在config/environment/production.rb等人:
1 2 | ActionController::Base.session_options[:session_domain] = [some domain] |
号
到目前为止,还不错——只要我所有的Rails应用程序都相同会话密钥和秘密,并且在同一域中,它们都可以使用同样的饼干。
但是,同事现在有一个JSP应用程序(在同一个域上)。他想看看我做的饼干。
因此,给定一个秘密和加密的cookie值,我们如何解密是为了得到饼干的内容吗?
(文档似乎表明这是默认的单向sha1加密--http://caboo.se/doc/classes/cgi/session/cookiestore.html——但是那么,我的Rails应用程序将如何读取cookie的内容单向加密?)
提前感谢您提供任何提示/指导/见解,
乔
如果直接从应用程序数据库中存储的会话数据中拉出session.data字段(如果您正在使用environment.rb文件中的活动记录存储)
1 | config.action_controller.session_store = :active_record_store |
号
…下面是您如何对其进行解码并返回散列值:
1 | Marshal.load(ActiveSupport::Base64.decode64(@session.data)) |
…或者在轨道上>=3.2(谢谢查克·沃斯)
1 | Marshal.load(Base64.decode64(@session.data)) |
。
它根本没有加密。
Rails使用hmac-sha1加密cookie数据,这与您怀疑的单向sha1加密不同(请参阅hmac上的维基百科文章了解解释)。加密由
1 2 3 4 5 6 7 8 9 10 11 12 | 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中实现这一点,您的同事将不得不复制EDCOX1×1的方法。源代码在您的gems目录(我的系统上的
以下是如何在Rails 4中解密会话cookie
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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-大象.com/2014-01/handling-rails-4-sessions-with-go/
默认情况下,Rails(在版本4之前)不加密会话cookie,它只对它们进行签名。要加密它们,您需要执行如下操作:
1 | ActionController::Base.session_store = EncryptedCookieStore |
有多个插件提供这种加密功能。
因此,如果您没有专门使用加密存储,那么所有Java代码需要做的是验证cookie签名并解码Cookie。正如亚历克斯在回答中所说的,你需要复制EDCOX1 1的功能,并与Java应用程序共享密钥。同时验证和解码cookie。
如果您不想验证签名(我不建议这样做),可以使用助产士的base64解码方法来查看会话哈希。在Ruby中,这是:
1 | Marshal.load(ActiveSupport::Base64.decode64(the_cookie_value)) |
。
我知道这是旧的,但希望这能帮助别人!
(更新:问题与Rails 3有关。从Rails 4开始,会话cookie默认加密。)
我写了一个Ruby Gem来处理由Rails应用程序管理的cookie。阅读它的来源,你可以理解它是如何工作的,并且可能将它移植到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。如果使用MSEHALL,那么将代码转换成Java可能是棘手的,因为您必须找到一个实现Ruby的MySal-yLoad的库。