In Rails 3 session cookie can easily decoded with base64 decoding but in Rails 4 cookies are encoded as well as encrypted.
I want to know how to read rails 4 cookie which is encoded as well as encrypted(assuming we know the secret key base).
Thanks,
Rails 4 uses AES-256 to encrypt cookies with the key based on your app's secret_token_base
.
Here's the general scheme of decrypting a session cookie:
- calc your secret key
- Base 64 decode the cookie value
- split the decoded cookie value by '--', this will result in two parts, the first part is the encrypted data and the second is the initialization vector used by the encryption scheme. Base 64 decode each part independently.
- decrypt the encrypted data by applying AES decryption with the secret key and the initialization vector.
I couldn't find a website to easily decrypt the messages (advice is welcome), programmatically it can be done like this:
secret = OpenSSL::PKCS5.pbkdf2_hmac_sha1(app_secret_token, 'encrypted cookie', 1000, 64)
encrypted_message = Base64.decode64(cookie_str)
cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
encrypted_data, iv = encrypted_message.split("--").map {|v| ::Base64.strict_decode64(v)}
cipher.decrypt
cipher.key = secret
cipher.iv = iv
decrypted_data = cipher.update(encrypted_data)
decrypted_data << cipher.final
Marshal.load(decrypted_data)
Couple of notes:
This code snippet is almost identical to the actual _decript
method implementation in ActiveSupport::MessageEncryptor
which is used by the ActionDispatch::Cookies
middelware.
This is all very much Rails 4 specific, from the ActionDispatch::Session::CookieJar:
If you only have secret_token set, your cookies will be signed, but not encrypted. This means a user cannot alter their +user_id+ without knowing your app's secret key, but can easily read their +user_id+. This was the default for Rails 3 apps.
If you have secret_key_base set, your cookies will be encrypted. This
goes a step further than signed cookies in that encrypted cookies cannot
be altered or read by users. This is the default starting in Rails 4.