Decrypting session strings wasn’t a big deal in previous versions of Rails, so I thought it should be pretty straightforward in Rails 4 as well. It took me a little while to figure out the magic Rails 4 does in order to encrypt cookies. As you may have noticed, secret_token
configuration option has been replaced by secret_key_base
. It seems the change is no accident, because the key is not used as a secret for encoding session data. The new encryption key is generated by running 1000 iterations of PBKDF2 function on secret_key_base
with a salt. Because ActiveSupport::MessageEncryptor
takes two arguments for encrypting and for verifying signature, two keys are generated using two different salts:
encrypted_cookie_salt
, default value:"encrypted cookie"
encrypted_signed_cookie_salt
, default value:"signed encrypted cookie"
Using these strings you can create a new instance of ActiveSupport::MessageEncryptor
. Don’t forget to CGI.unescape
your cookie before decrypting.
message = CGI.unescape("VXVHWGQra3JpclBiSkpZWW8yMTRzWUVQL0tYajNXMXUyZzFNcFlNcjVVdloxMnhWOFRvdGdPcXhJV256ZEx3MzFkbWhWbG1SSmMzK0NqNHZnS1BPKytTWVRHRFhjN1hWOHlmc3VnNk5rOXRQNzdobnFlOFhPT25NSTVlT3d2QkZiQktvRU5jMWlNdUZKWjFNL0lBbE9WSEVkcXFoMnUzNGtBa0kzRHJMWFd6VEIreHVjVlhSMThxZEQ2VmdKRmtrWXFKQlI4d1k3QU9EbnViVXR2ZWZxZz09LS00bUd0K0g3UTM0RkY1THkrZUt6Slh3PT0%3D--d9847b41c72ceed939cb58acb6cb989d58602d6e")
config = Rails.application.config
key_generator = ActiveSupport::KeyGenerator.new(
config.secret_key_base, iterations: 1000
)
secret = key_generator.generate_key(
config.action_dispatch.encrypted_cookie_salt
)
sign_secret = key_generator.generate_key(
config.action_dispatch.encrypted_signed_cookie_salt
)
encryptor = ActiveSupport::MessageEncryptor.new(
secret, sign_secret
)
encryptor.decrypt_and_verify(message)