|
require "cgi" |
|
require "base64" |
|
require "openssl" |
|
require "json" |
|
|
|
def generate_key(salt, key_size = 64) |
|
secret_key_base = '' |
|
OpenSSL::PKCS5.pbkdf2_hmac_sha1(secret_key_base, salt, 1000, key_size) |
|
end |
|
|
|
def decrypt_message(signed_message) |
|
secret = generate_key("encrypted cookie") |
|
|
|
data, digest = signed_message.split("--") |
|
encrypted_message = ::Base64.strict_decode64(data) |
|
encrypted_data, iv = encrypted_message.split("--").map {|v| ::Base64.strict_decode64(v)} |
|
|
|
cipher = OpenSSL::Cipher.new('aes-256-cbc') |
|
cipher.decrypt |
|
cipher.key = secret[0, cipher.key_len] |
|
cipher.iv = iv |
|
decrypted_data = cipher.update(encrypted_data) |
|
decrypted_data << cipher.final |
|
|
|
[JSON.load(decrypted_data), iv] |
|
end |
|
|
|
def sign_object(json, iv) |
|
secret = generate_key("encrypted cookie") |
|
sign_secret = generate_key("signed encrypted cookie") |
|
|
|
decrypted_data = JSON.dump(json) |
|
|
|
cipher = OpenSSL::Cipher.new('aes-256-cbc') |
|
cipher.encrypt |
|
cipher.key = secret[0, cipher.key_len] |
|
cipher.iv = iv |
|
encrypted_data = cipher.update(decrypted_data) |
|
encrypted_data << cipher.final |
|
|
|
encrypted_message = "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}" |
|
data = ::Base64.strict_encode64(encrypted_message) |
|
digest = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get("SHA1").new, sign_secret, data) |
|
|
|
"#{data}--#{digest}" |
|
end |
|
|
|
cookie = '' |
|
signed_message = CGI.unescape(cookie) |
|
json, iv = decrypt_message(signed_message) |
|
puts json |
|
|
|
json['user_id'] = 1 |
|
|
|
cookie = sign_object(json, iv) |
|
puts cookie |