Rails Rails 把 Cookie 加密之后为什么还要加一个 Signature?

lmorenbit · June 11, 2014 · Last by y0unge replied at November 01, 2023 · 4835 hits

本来就用 aes-256-cbc 加密然后用 Base64 编码,为什么还要加上个 Signature? 谁能解释一下不?

服务器根据签名来判断 cookie 中的内容是否被伪造

http://mednoter.com/rails-session-2.html

解决的是不同的问题,加密是将内容变成密文;签名是防篡改

@xiaoronglv @sunday35034 谢谢,文章很赞

这里面的 salt 是随机的,即使有 cookie,有 secret_key_base,我也想不出还有什么办法可以解出来。签名是防篡改,但是如果改了之后 cookie 完全没用,为什么要防呢?

# This can be used in situations similar to the <tt>MessageVerifier</tt>, but
# where you don't want users to be able to determine the value of the payload.
#
#   salt  = SecureRandom.random_bytes(64)
#   key   = ActiveSupport::KeyGenerator.new('password').generate_key(salt) # => "\x89\xE0\x156\xAC..."
#   crypt = ActiveSupport::MessageEncryptor.new(key)                       # => #<ActiveSupport::MessageEncryptor ...>
#   encrypted_data = crypt.encrypt_and_sign('my secret data')              # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
#   crypt.decrypt_and_verify(encrypted_data)                               # => "my secret data"

签名应该可以验证 cookie 完整性

文章里有一段不是有解释嘛

正文只是简单的编码,并未加密的。如果用户(userid = 13134)篡改了正文(userid = 2),就有访问其他用户信息的风险。
为了防止cookie被篡改,每一个session字符串的尾巴上都带着一个服务器生成的digest。
若用户的content与digest不匹配,服务器就知道这个cookie是伪造的。

#5 楼 @sunday35034 是这样的,Rails 4.1 本身已经对 cookie 加密了(而且有 salt)不是只用 Base64 编码

@xiaoronglv 请问你的 Rails 版本多少?或者文中的正文是怎么得到的?

我从 cookie 里拿到的 session 是

Q3NpYk8veW15aXQ1dWgxZGhldCtPU3ZYRTh2SWxacnlGcExWYTJtUXFvRkI3QzZodVl1MW5ZY2VSalI2OVZiSEdOSUcyYXQ4NDNQSGt3djByd0NxZWtZVTA2eUZpc090blJwNE1td0ZiNnMvdzQ3OTRUczd1Q1M5dG5LdlZvbjVrWUlScEtwNEdqd2xJaCt1RGJKa3pCK3FEak0wYXFJS21HTmtiYXdFR3R6V0NhdERZU0dFSlE0ejhqMDN3TVM5bGRhQzdjU3lwb1NseXVGMXJUK1pJc0pKMkI3a0ZiTkYwbW9oMjZndDY2WVlVTGhMa1RiSkNQMEduY1pLYytBZWMwZmFjRDFRU0lXTWZTMnkzdWVMUThoOHFyL3B5OFcyaFJnRytOOVhKZTRoQ1Y4MVgvSjJ6NEJCVWF2bkZkT3otLWdkT3VnaUpnKytjQWlkYUswL123456PQ==--63f0c6963b5adfe7b947d8ef750ddc284650860c

Base64 解码后

CsibO/ymyit5uh1dhet+OSvXE8vIlZryFpLVa2mQqoFB7C6huYu1nYceRjR69VbHGNIG2at843PHkwv0rwCqekYU06yFisOtnRp4MmwFb6s/w4794Ts7uCS9tnKvVon5kYIRpKp4GjwlIh+uDbJkzB+qDjM0aqIKmGNkbawEGtzWCatDYSGEJQ4z8j03wMS9ldaC7cSypoSlyuF1rT+ZIsJJ2B7kFbNF0moh26gt66YYULhLkTbJCP0GncZKc+Aec0facD1QSIWMfS2y3ueLQ8h8qr/py8W2hRgG+N9XJe4hCV81X/J2z4BBUavnFdOz--gdOugiJg++cAidaK012345==

另外 salt 是怎么保存的?

不要用上面的 Cookie 直接解码,我改过几个字符

个人觉得这个事情不用太深究,因为安全这个毕竟是一个相对的事情,每个环节都可能出现安全问题,你不能先建立“加了密就是绝对安全”这个假命题的基础上讨论这个问题。假如别人通过渠道拿到了你的 salt,也知道你的加密算法,但是不知道你的签名算法,这时候签名就有用了。

反过来,既然 Rails 4.1 都给 cookies 加密了,为什么 ruby-china 还要用 ssl 呢?

不过还是很欣赏 LZ 打破砂锅问到底的钻研精神

#7 楼 @sunday35034 解决的是不同问题

cookie 加密并不能解决登录过程中用户名和密码被劫持的问题

#8 楼 @kingwkb 对,密文一样可以被劫持。照样能冒充你

@sunday35034 你说得对

Cookie 的加密方法: http://dev.housetrip.com/2014/01/14/session-store-and-security/

我上面提到的 salt,大家都是一样的(如果你没改过): "encrypted cookie",但是 rails 还会进一步编码之后才用。具体看文章

这个代码我分析过,当前的 cookie 加密方式用的是 aes cbc,如果不加签名对于一般人也伪造不了,因为 sk 不可知。但是,这个加密算法在这里使用是存在的漏洞,具体可以搜索 padding oracle,在不知道 key 的情况下,可以还原出明文,且可以伪造出一个合法的 cookie。

You need to Sign in before reply, if you don't have an account, please Sign up first.