2017-01-04 3 views
1

私はRails 5セッションクッキーを手動で解読するには?

  • config.action_dispatch.encrypted_cookie_salt
  • config.action_dispatch.encrypted_signed_cookie_salt
  • secrets.secret_key_base
  • へのアクセス権を持っている(--を含む)完全なクッキー文字列

私はRailsの4(Rails 4: How to decrypt rails 4 session cookie (Given the session key and secret))でこれを行う方法を参照してくださいしかし、これらはRails 5では動作しないようです。

答えて

7

私は、先日も同じ問題を抱えていて、生成された秘密が64バイト(私のMacでは)長かったが、Railsはキーが32バイト長であることを確認しました(source)。

は、これは私のために働いています

require 'cgi' 
require 'json' 
require 'active_support' 

def verify_and_decrypt_session_cookie(cookie, secret_key_base) 



cookie = CGI::unescape(cookie) 
    salt   = 'encrypted cookie' 
    signed_salt = 'signed encrypted cookie' 
    key_generator = ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000) 
    secret = key_generator.generate_key(salt)[0, ActiveSupport::MessageEncryptor.key_len] 
    sign_secret = key_generator.generate_key(signed_salt) 
    encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON) 

    encryptor.decrypt_and_verify(cookie) 
end 

またはActiveSupportなし:https://gist.github.com/mbyczkowski/34fb691b4d7a100c32148705f244d028

require 'openssl' 
require 'base64' 
require 'cgi' 
require 'json' 

def verify_and_decrypt_session_cookie cookie, secret_key_base 
    cookie = CGI.unescape(cookie) 

    ################# 
    # generate keys # 
    ################# 
    encrypted_cookie_salt = 'encrypted cookie' # default: Rails.application.config.action_dispatch.encrypted_cookie_salt 
    encrypted_signed_cookie_salt = 'signed encrypted cookie' # default: Rails.application.config.action_dispatch.encrypted_signed_cookie_salt 
    iterations = 1000 
    key_size = 64 
    secret = OpenSSL::PKCS5.pbkdf2_hmac_sha1(secret_key_base, encrypted_cookie_salt, iterations, key_size)[0, OpenSSL::Cipher.new('aes-256-cbc').key_len] 
    sign_secret = OpenSSL::PKCS5.pbkdf2_hmac_sha1(secret_key_base, encrypted_signed_cookie_salt, iterations, key_size) 

    ########## 
    # Verify # 
    ########## 
    data, digest = cookie.split('--') 
    raise 'invalid message' unless digest == OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, sign_secret, data) 
    # you better use secure compare instead of `==` to prevent time based attact, 
    # ref: ActiveSupport::SecurityUtils.secure_compare 

    ########### 
    # Decrypt # 
    ########### 
    encrypted_message = Base64.strict_decode64(data) 
    encrypted_data, iv = encrypted_message.split('--').map{|v| Base64.strict_decode64(v) } 
    cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc') 
    cipher.decrypt 
    cipher.key = secret 
    cipher.iv = iv 
    decrypted_data = cipher.update(encrypted_data) 
    decrypted_data << cipher.final 

    JSON.load(decrypted_data) 
end 

要旨にコメントすること自由に感じ

関連する問題