在rails中加密会话信息

时间:2012-11-30 20:44:14

标签: ruby-on-rails security

默认情况下,rails使用cookie存储来存储会话信息。我接下来的教程说它是最好的方式,速度超快,而且都加密了。但是当我base64解码cookie内容时,我可以在那里看到我的会话信息。它混合成了许多乱码,但它就在那里。

我在这里缺少什么?

rails不使用该秘密令牌来加密cookie中的信息吗?我怎么能这样做?

1 个答案:

答案 0 :(得分:3)

Rails使用秘密令牌签署会话。原始数据仍然存在,但更改它将导致它不再匹配签名,Rails将拒绝它。 cookie字符串看起来像session_data--signature,会话数据是base64编码的编组对象,签名是HMAC(session string, secret token)

会话数据的一般假设是它不是秘密(因为它通常应该只包含一些内容,如CSRF令牌和用户ID),但它不应该由用户更改。 cookie签名完成了这一点。

如果您需要实际加密数据以便用户永远无法看到它,您可以使用OpenSSL对称加密之类的方式进行加密,或者您可以切换到非cookie数据存储。

这是我自己的应用程序的cookie商店的变种;我没有测试过,但理论上这应该为您生成实际加密的cookie。请注意,这将明显慢于默认cookie存储,并且根据其运行时,可能是DOS向量。此外,加密数据将比未加密数据更长,会话cookie限制为4kb,因此如果您在会话中存储大量数据,这可能会导致您超过该限制。

# Define our message encryptor
module ActiveSupport
  class EncryptedMessageVerifier < MessageVerifier
    def verify(message)
      Marshal.load cryptor.decrypt_and_verify(message)
    end

    def generate(value)
      cryptor.encrypt_and_sign Marshal.dump(value)
    end

    def cryptor
      ActiveSupport::MessageEncryptor.new(@secret)
    end
  end
end

# And then patch it into SignedCookieJar
class ActionDispatch::Cookies::SignedCookieJar
  def initialize(parent_jar, secret)
    ensure_secret_secure(secret)
    @parent_jar = parent_jar
    @verifier   = ActiveSupport::EncryptedMessageVerifier.new(secret)
  end
end