本来就用 aes-256-cbc 加密然后用 Base64 编码,为什么还要加上个 Signature? 谁能解释一下不?
@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"
文章里有一段不是有解释嘛
正文只是简单的编码,并未加密的。如果用户(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 打破砂锅问到底的钻研精神
@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。