encrypted_cookie 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0352358d7b487ba0caebdc794eb34832213b01a8
4
+ data.tar.gz: 017a9b0e14be94789516403de3e3a13c511b4445
5
+ SHA512:
6
+ metadata.gz: c011384dc4191e17eec7e598b6b89b5e4c327202b9b78decb8d26dcf2f8fceb0416c8c3182b744bd17819f188f09c56dc5add8a64542d2792e9e4b8d7103935f
7
+ data.tar.gz: 59f8667546f117c5786e8ed9230f8757bf91cc4f012a5975440c3dce5fb18054eeda0d08ade721190a6392e95f9c8f64f7640fe5e386851a184bf220b356cdb0
@@ -1,6 +1,6 @@
1
1
  ## Encrypted session cookies for Rack (and therefore Sinatra)
2
2
 
3
- The `encrypted_cookie` gem provides 128-bit-AES-encrypted, tamper-proof cookies
3
+ The `encrypted_cookie` gem provides 256-bit-AES-encrypted, tamper-proof cookies
4
4
  for Rack through the class `Rack::Session::EncryptedCookie`.
5
5
 
6
6
  ## How to use encrypted\_cookie
@@ -20,16 +20,37 @@ Sinatra example:
20
20
  "session: " + session.inspect
21
21
  end
22
22
 
23
- _*_ Your `:secret` must be at least 16 bytes long and should be really random.
23
+ _*_ Your `:secret` must be at least 32 bytes long and should be really random.
24
+ Don't use a password or passphrase, generate something random (see below).
24
25
 
25
26
  ## Encryption and integrity protection
26
27
 
27
- The cookie encryption method is 128-bit AES (with salt). Additionally, the
28
- cookies are integrity protected with Rack's built-in HMAC support, which means
29
- that if a user tampers with their cookie in any way, their session will
30
- immediately be reset to `{}` (empty hash).
28
+ The cookie is encrypted with 256-bit AES in CBC mode (with random IV). The
29
+ encrypted cookie is then signed with a HMAC, to prevent tampering and chosen
30
+ ciphertext attacks. Any attempt at tampering with the cookie will reset the
31
+ user to `{}` (empty hash).
31
32
 
32
33
  ## Generating a good secret
33
34
 
34
- require 'openssl'
35
- puts OpenSSL::Random.random_bytes(16).inspect
35
+ Run this in a terminal and paste the output into your script:
36
+
37
+ $ ruby -rsecurerandom -e "puts SecureRandom.hex(32)"
38
+
39
+ ## Developing
40
+
41
+ To get the specs running:
42
+
43
+ ```bash
44
+ $ cd path-to-clone
45
+ $ gem install bundler # if not already installed
46
+ $ bundle install
47
+ $ bundle exec rspec
48
+ ```
49
+
50
+ # Thanks
51
+
52
+ - [@namelessjon](https://github.com/namelessjon) - Jon - For the massive crypto improvements!
53
+ - [@mkristian](https://github.com/mkristian) - Christian Meier
54
+ - [@danp](https://github.com/danp) - Dan Peterson
55
+ - [@stmllr](https://github.com/stmllr) - Steffen Müller
56
+ - [@andrhamm](https://github.com/andrhamm) - Andrew Hammond
data/Rakefile CHANGED
@@ -8,5 +8,6 @@ Echoe.new('encrypted_cookie', '0.0.4') do |p|
8
8
  p.author = "Christian von Kleist"
9
9
  p.email = "cvonkleist at-a-place-called gmail.com"
10
10
  p.ignore_pattern = ["tmp/*", "script/*"]
11
- p.development_dependencies = []
11
+ p.runtime_dependencies = ["rack >=1.1 <3"]
12
+ p.development_dependencies = ["rack-test ~>0.6.2", "sinatra ~>1.3.4", "rspec ~>2.14.1"]
12
13
  end
@@ -1,32 +1,41 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  Gem::Specification.new do |s|
4
- s.name = %q{encrypted_cookie}
5
- s.version = "0.0.4"
4
+ s.name = "encrypted_cookie"
5
+ s.version = "0.0.5"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Christian von Kleist"]
9
- s.cert_chain = ["/home/cvk/.gemcert/gem-public_cert.pem"]
10
- s.date = %q{2011-03-03}
11
- s.description = %q{Encrypted session cookies for Rack}
12
- s.email = %q{cvonkleist at-a-place-called gmail.com}
9
+ s.date = "2017-11-27"
10
+ s.description = "Encrypted session cookies for Rack"
11
+ s.email = "cvonkleist at-a-place-called gmail.com"
13
12
  s.extra_rdoc_files = ["README.markdown", "lib/encrypted_cookie.rb"]
14
- s.files = ["Manifest", "README.markdown", "Rakefile", "encrypted_cookie.gemspec", "lib/encrypted_cookie.rb", "spec/encrypted_cookie_spec.rb"]
15
- s.homepage = %q{http://github.com/cvonkleist/encrypted_cookie}
13
+ s.files = ["Manifest", "README.markdown", "Rakefile", "encrypted_cookie.gemspec", "lib/encrypted_cookie.rb", "lib/encrypted_cookie/encryptor.rb", "spec/encrypted_cookie_spec.rb"]
14
+ s.homepage = "http://github.com/cvonkleist/encrypted_cookie"
16
15
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Encrypted_cookie", "--main", "README.markdown"]
17
16
  s.require_paths = ["lib"]
18
- s.rubyforge_project = %q{encrypted_cookie}
19
- s.rubygems_version = %q{1.3.7}
20
- s.signing_key = %q{/home/cvk/.gemcert/gem-private_key.pem}
21
- s.summary = %q{Encrypted session cookies for Rack}
17
+ s.rubyforge_project = "encrypted_cookie"
18
+ s.rubygems_version = "2.0.3"
19
+ s.summary = "Encrypted session cookies for Rack"
22
20
 
23
21
  if s.respond_to? :specification_version then
24
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
- s.specification_version = 3
22
+ s.specification_version = 4
26
23
 
27
24
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
25
+ s.add_runtime_dependency(%q<rack>, ["< 3", ">= 1.1"])
26
+ s.add_development_dependency(%q<rack-test>, ["~> 0.6.2"])
27
+ s.add_development_dependency(%q<sinatra>, ["~> 1.3.4"])
28
+ s.add_development_dependency(%q<rspec>, ["~> 2.14.1"])
28
29
  else
30
+ s.add_dependency(%q<rack>, ["< 3", ">= 1.1"])
31
+ s.add_dependency(%q<rack-test>, ["~> 0.6.2"])
32
+ s.add_dependency(%q<sinatra>, ["~> 1.3.4"])
33
+ s.add_dependency(%q<rspec>, ["~> 2.14.1"])
29
34
  end
30
35
  else
36
+ s.add_dependency(%q<rack>, ["< 3", ">= 1.1"])
37
+ s.add_dependency(%q<rack-test>, ["~> 0.6.2"])
38
+ s.add_dependency(%q<sinatra>, ["~> 1.3.4"])
39
+ s.add_dependency(%q<rspec>, ["~> 2.14.1"])
31
40
  end
32
41
  end
@@ -1,15 +1,15 @@
1
- require 'openssl'
2
1
  require 'rack/request'
3
2
  require 'rack/response'
3
+ require 'encrypted_cookie/encryptor'
4
4
 
5
5
  module Rack
6
6
 
7
7
  module Session
8
8
 
9
- # Rack::Session::EncryptedCookie provides AES-128-encrypted, tamper-proof
9
+ # Rack::Session::EncryptedCookie provides AES-256-encrypted, tamper-proof
10
10
  # cookie-based session management.
11
11
  #
12
- # The session is Marshal'd, HMAC'd, and encrypted.
12
+ # The session is Marshal'd, encrypted and HMAC'd.
13
13
  #
14
14
  # Example:
15
15
  #
@@ -19,11 +19,22 @@ module Rack
19
19
  # :domain => 'foo.com',
20
20
  # :path => '/',
21
21
  # :expire_after => 2592000
22
+ # :time_to_live => 600
22
23
  #
23
24
  # All parameters are optional except :secret.
24
-
25
+ #
26
+ # The default for the session time-to-live is 30 minutes. You can set
27
+ # the timeout on per session base by adding the expiration time in the
28
+ # session:
29
+ # session[Rack::Session::EncryptedCookie::EXPIRES] = Time.now + 120
30
+ #
31
+ # Note that you shouldn't trust the expire_after parameter in the cookie
32
+ # for session expiry as that can be altered by the recipient. Instead,
33
+ # use time_to_live which is server side check.
25
34
  class EncryptedCookie
26
35
 
36
+ EXPIRES = '_encrypted_cookie_expires_'
37
+
27
38
  def initialize(app, options={})
28
39
  @app = app
29
40
  @key = options[:key] || "rack.session"
@@ -31,7 +42,9 @@ module Rack
31
42
  fail "Error! A secret is required to use encrypted cookies. Do something like this:\n\nuse Rack::Session::EncryptedCookie, :secret => YOUR_VERY_LONG_VERY_RANDOM_SECRET_KEY_HERE" unless @secret
32
43
  @default_options = {:domain => nil,
33
44
  :path => "/",
45
+ :time_to_live => 1800,
34
46
  :expire_after => nil}.merge(options)
47
+ @encryptor = Encryptor.new(@secret)
35
48
  end
36
49
 
37
50
  def call(env)
@@ -42,40 +55,45 @@ module Rack
42
55
 
43
56
  private
44
57
 
58
+ def remove_expiration(session_data)
59
+ expires = session_data.delete(EXPIRES)
60
+ if expires and expires < Time.now
61
+ session_data.clear
62
+ end
63
+ end
64
+
45
65
  def load_session(env)
46
66
  request = Rack::Request.new(env)
67
+ env["rack.session.options"] = @default_options.dup
68
+
47
69
  session_data = request.cookies[@key]
70
+ session_data = @encryptor.decrypt(session_data)
71
+ session_data = Marshal.load(session_data)
72
+ remove_expiration(session_data)
48
73
 
49
- if session_data
50
- if session_data = decrypt(session_data)
51
- session_data, digest = session_data.split("--")
52
- session_data = nil unless digest == generate_hmac(session_data)
53
- end
54
- end
74
+ env["rack.session"] = session_data
75
+ rescue
76
+ env["rack.session"] = Hash.new
77
+ end
55
78
 
56
- begin
57
- session_data = session_data.unpack("m*").first
58
- session_data = Marshal.load(session_data)
59
- env["rack.session"] = session_data
60
- rescue
61
- env["rack.session"] = Hash.new
79
+ def add_expiration(session_data, options)
80
+ if options[:time_to_live] && !session_data.key?(EXPIRES)
81
+ expires = Time.now + options[:time_to_live]
82
+ session_data.merge!({EXPIRES => expires})
62
83
  end
63
-
64
- env["rack.session.options"] = @default_options.dup
65
84
  end
66
85
 
67
86
  def commit_session(env, status, headers, body)
68
- session_data = Marshal.dump(env["rack.session"])
69
- session_data = [session_data].pack("m*")
87
+ options = env["rack.session.options"]
70
88
 
71
- session_data = "#{session_data}--#{generate_hmac(session_data)}"
72
-
73
- session_data = encrypt(session_data)
89
+ session_data = env["rack.session"]
90
+ add_expiration(session_data, options)
91
+ session_data = Marshal.dump(session_data)
92
+ session_data = @encryptor.encrypt(session_data)
74
93
 
75
94
  if session_data.size > (4096 - @key.size)
76
95
  env["rack.errors"].puts("Warning! Rack::Session::Cookie data size exceeds 4K. Content dropped.")
77
96
  else
78
- options = env["rack.session.options"]
79
97
  cookie = Hash.new
80
98
  cookie[:value] = session_data
81
99
  cookie[:expires] = Time.now + options[:expire_after] unless options[:expire_after].nil?
@@ -84,38 +102,6 @@ module Rack
84
102
 
85
103
  [status, headers, body]
86
104
  end
87
-
88
- def generate_hmac(data)
89
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, @secret, data)
90
- end
91
-
92
- def encrypt(str)
93
- aes = OpenSSL::Cipher::Cipher.new('aes-128-cbc').encrypt
94
- aes.key = @secret
95
- iv = OpenSSL::Random.random_bytes(aes.iv_len)
96
- aes.iv = iv
97
- [iv + (aes.update(str) << aes.final)].pack('m0')
98
- end
99
-
100
- # decrypts string. returns nil if an error occurs
101
- #
102
- # returns nil if openssl raises an error during decryption (likely
103
- # someone is tampering with the session data, or the sinatra user was
104
- # previously using Cookie and has just switched to EncryptedCookie), and
105
- # will also return nil if the text to decrypt is too short to possibly be
106
- # good aes data.
107
- def decrypt(str)
108
- str = str.unpack('m0').first
109
- aes = OpenSSL::Cipher::Cipher.new('aes-128-cbc').decrypt
110
- aes.key = @secret
111
- iv = str[0, aes.iv_len]
112
- aes.iv = iv
113
- crypted_text = str[aes.iv_len..-1]
114
- return nil if crypted_text.nil? || iv.nil?
115
- aes.update(crypted_text) << aes.final
116
- rescue
117
- nil
118
- end
119
105
  end
120
106
  end
121
107
  end
@@ -0,0 +1,123 @@
1
+ require 'openssl'
2
+ require 'rack/utils'
3
+ module Rack
4
+ module Session
5
+ class EncryptedCookie
6
+ # Encrypts messages with authentication
7
+ #
8
+ # The use of authentication is essential to avoid Chosen Ciphertext
9
+ # Attacks. By using this in an encrypt then MAC form, we avoid some
10
+ # attacks such as e.g. being used as a CBC padding oracle to decrypt
11
+ # the ciphertext.
12
+ class Encryptor
13
+ # Create the encryptor
14
+ #
15
+ # Pass in the secret, which should be at least 32-bytes worth of
16
+ # entropy, e.g. a string generated by `SecureRandom.hex(32)`.
17
+ # This also allows specification of the algorithm for the cipher
18
+ # and MAC. But don't change that unless you're very sure.
19
+ def initialize(secret, cipher = 'aes-256-cbc', hmac = 'SHA256')
20
+ @cipher = cipher
21
+ @hmac = hmac
22
+
23
+ # use the HMAC to derive two independent keys for the encryption and
24
+ # authentication of ciphertexts It is bad practice to use the same key
25
+ # for encryption and authentication. This also allows us to use all
26
+ # of the entropy in a long key (e.g. 64 hex bytes) when straight
27
+ # assignement would could result in assigning a key with a much
28
+ # reduced key space. Also, the personalisation strings further help
29
+ # reduce the possibility of key reuse by ensuring it should be unique
30
+ # to this gem, even with shared secrets.
31
+ @encryption_key = hmac("EncryptedCookie Encryption", secret)
32
+ @authentication_key = hmac("EncryptedCookie Authentication", secret)
33
+ end
34
+
35
+ # Encrypts message
36
+ #
37
+ # Returns the base64 encoded ciphertext plus IV. In addtion, the
38
+ # message is prepended with a MAC code to prevent chosen ciphertext
39
+ # attacks.
40
+ def encrypt(message)
41
+ # encrypt the message
42
+ encrypted = encrypt_message(message)
43
+
44
+ [authenticate_message(encrypted) + encrypted].pack('m0')
45
+ end
46
+
47
+ # decrypts base64 encoded ciphertext
48
+ #
49
+ # First, it checks the message tag and returns nil if that fails to verify.
50
+ # Otherwise, the data is passed on to the AES function for decryption.
51
+ def decrypt(ciphertext)
52
+ ciphertext = ciphertext.unpack('m').first
53
+ tag = ciphertext[0, hmac_length]
54
+ ciphertext = ciphertext[hmac_length..-1]
55
+
56
+ # make sure we actually had enough data for the tag too.
57
+ if tag && ciphertext && verify_message(tag, ciphertext)
58
+ decrypt_ciphertext(ciphertext)
59
+ else
60
+ nil
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ # HMAC digest of the message using the given secret
67
+ def hmac(secret, message)
68
+ OpenSSL::HMAC.digest(@hmac, secret, message)
69
+ end
70
+
71
+ def hmac_length
72
+ OpenSSL::Digest.new(@hmac).size
73
+ end
74
+
75
+ # returns the message authentication tag
76
+ #
77
+ # This is computed as HMAC(authentication_key, message)
78
+ def authenticate_message(message)
79
+ hmac(@authentication_key, message)
80
+ end
81
+
82
+ # verifies the message
83
+ #
84
+ # This does its best to be constant time, by use of the rack secure compare
85
+ # function.
86
+ def verify_message(tag, message)
87
+ own_tag = authenticate_message(message)
88
+ Rack::Utils.secure_compare(tag, own_tag)
89
+ end
90
+
91
+ # Encrypt
92
+ #
93
+ # Encrypts the given message with a random IV, then returns the ciphertext
94
+ # with the IV prepended.
95
+ def encrypt_message(message)
96
+ aes = OpenSSL::Cipher.new(@cipher).encrypt
97
+ aes.key = @encryption_key
98
+ iv = aes.random_iv
99
+ aes.iv = iv
100
+ iv + (aes.update(message) << aes.final)
101
+ end
102
+
103
+ # Decrypt
104
+ #
105
+ # Pulls the IV off the front of the message and decrypts. Catches
106
+ # OpenSSL errors and returns nil. But this should never happen, as the
107
+ # verify method should catch all corrupted ciphertexts.
108
+ def decrypt_ciphertext(ciphertext)
109
+ aes = OpenSSL::Cipher.new(@cipher).decrypt
110
+ aes.key = @encryption_key
111
+ iv = ciphertext[0, aes.iv_len]
112
+ aes.iv = iv
113
+ crypted_text = ciphertext[aes.iv_len..-1]
114
+ return nil if crypted_text.nil? || iv.nil?
115
+ aes.update(crypted_text) << aes.final
116
+ rescue
117
+ nil
118
+ end
119
+
120
+ end
121
+ end
122
+ end
123
+ end
@@ -1,20 +1,36 @@
1
1
  require 'rack/test'
2
- require 'sinatra'
2
+ require 'sinatra/base'
3
3
  require 'rspec'
4
4
  require 'cgi'
5
- require File.dirname(__FILE__) + '/../lib/encrypted_cookie'
5
+ require './lib/encrypted_cookie'
6
6
 
7
7
  include Rack::Session
8
8
 
9
+
10
+ module Helper
11
+ def unpack_cookie
12
+ data = last_response.headers['Set-Cookie'][/rack.session=(.*?);/, 1]
13
+ data = data.split('--').first
14
+ str = CGI.unescape(data).unpack('m').first
15
+ end
16
+ end
17
+
18
+
9
19
  RSpec.configure do |conf|
10
20
  conf.include Rack::Test::Methods
21
+ conf.include Helper
11
22
  end
12
23
 
13
24
  class EncryptedApp < Sinatra::Application
14
- use Rack::Session::EncryptedCookie, :secret => 'foo' * 10
25
+ disable :show_exceptions
26
+ use Rack::Session::EncryptedCookie, :secret => 'foo' * 10, :time_to_live => 0.1
15
27
  get '/' do
16
28
  "session: " + session.inspect
17
29
  end
30
+ get '/timeout/:value' do
31
+ session[Rack::Session::EncryptedCookie::EXPIRES] = Time.now + params[:value].to_i
32
+ "timeout set"
33
+ end
18
34
  get '/set/:key/:value' do
19
35
  session[params[:key]] = params[:value]
20
36
  "all set"
@@ -23,8 +39,10 @@ end
23
39
 
24
40
  # this app has cookie integrity protection, but not encryption
25
41
  class UnencryptedApp < Sinatra::Application
42
+ disable :show_exceptions
26
43
  use Rack::Session::Cookie, :secret => 'foo' * 10
27
44
  get '/' do
45
+ session[:foo] = 'bar'
28
46
  "session: " + session.inspect
29
47
  end
30
48
  end
@@ -32,7 +50,7 @@ end
32
50
  describe EncryptedCookie do
33
51
  it 'should fail if no secret is specified' do
34
52
  lambda { EncryptedCookie.new(nil) }.should raise_error(/A secret is required/)
35
- lambda { EncryptedCookie.new(nil, :secret => 'foo') }.should_not raise_error(/A secret is required/)
53
+ lambda { EncryptedCookie.new(nil, :secret => 'foo') }.should_not raise_error
36
54
  end
37
55
  end
38
56
 
@@ -51,18 +69,6 @@ describe EncryptedApp do
51
69
  get '/'
52
70
  last_response.body.should == 'session: {"foo"=>"bar"}'
53
71
  last_response.headers['Set-Cookie'].should_not include("BAh7AA")
54
-
55
- data = last_response.headers['Set-Cookie'][/rack.session=(.*?);/, 1]
56
- str = CGI.unescape(data).unpack('m0').first
57
- aes = OpenSSL::Cipher::Cipher.new('aes-128-cbc').decrypt
58
- aes.key = 'foo' * 10
59
- aes.iv = str[0, aes.iv_len]
60
- crypted_text = str[aes.iv_len..-1]
61
-
62
- plaintext = (aes.update(crypted_text) << aes.final)
63
- base64_marshal_data, hmac = plaintext.split('--')
64
- session_hash = Marshal.load(base64_marshal_data.unpack('m0').first)
65
- session_hash.should == {"foo" => "bar"}
66
72
  end
67
73
  it "should make encrypted session data that can't be decrypted with the wrong key" do
68
74
  get '/set/foo/bar'
@@ -71,12 +77,11 @@ describe EncryptedApp do
71
77
  last_response.body.should == 'session: {"foo"=>"bar"}'
72
78
  last_response.headers['Set-Cookie'].should_not include("BAh7AA")
73
79
 
74
- data = last_response.headers['Set-Cookie'][/rack.session=(.*?);/, 1]
75
- str = CGI.unescape(data).unpack('m0').first
76
- aes = OpenSSL::Cipher::Cipher.new('aes-128-cbc').decrypt
80
+ data = unpack_cookie
81
+ aes = OpenSSL::Cipher.new('aes-128-cbc').decrypt
77
82
  aes.key = 'bar' * 10
78
- iv = str[0, aes.iv_len]
79
- crypted_text = str[aes.iv_len..-1]
83
+ iv = data[0, aes.iv_len]
84
+ crypted_text = data[aes.iv_len..-1]
80
85
 
81
86
  lambda { plaintext = (aes.update(crypted_text) << aes.final) }.should raise_error("bad decrypt")
82
87
  end
@@ -98,6 +103,25 @@ describe EncryptedApp do
98
103
  get '/'
99
104
  last_response.body.should == 'session: {}'
100
105
  end
106
+ it "should reset the session on timeout" do
107
+ get '/set/foo/bar'
108
+ last_response.body.should == 'all set'
109
+ get '/'
110
+ last_response.body.should == 'session: {"foo"=>"bar"}'
111
+ sleep 0.08
112
+ get '/'
113
+ last_response.body.should == 'session: {"foo"=>"bar"}'
114
+ sleep 0.08
115
+ get '/'
116
+ last_response.body.should == 'session: {"foo"=>"bar"}'
117
+ sleep 0.1
118
+ get '/'
119
+ last_response.body.should == 'session: {}'
120
+ get '/timeout/0'
121
+ last_response.body.should == 'timeout set'
122
+ get '/'
123
+ last_response.body.should == 'session: {}'
124
+ end
101
125
  end
102
126
 
103
127
  describe UnencryptedApp do
@@ -106,7 +130,7 @@ describe UnencryptedApp do
106
130
  end
107
131
  it "should include unencrypted marshal'd data" do
108
132
  get '/'
109
- last_response.body.should == 'session: {}'
110
- last_response.headers['Set-Cookie'].should include("BAh7AA")
133
+ cookie = Marshal.load(unpack_cookie)
134
+ cookie['foo'].should == 'bar'
111
135
  end
112
136
  end
metadata CHANGED
@@ -1,100 +1,119 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: encrypted_cookie
3
- version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 0
9
- - 4
10
- version: 0.0.4
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Christian von Kleist
14
8
  autorequire:
15
9
  bindir: bin
16
- cert_chain:
17
- - |
18
- -----BEGIN CERTIFICATE-----
19
- MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMRMwEQYDVQQDDApjdm9u
20
- a2xlaXN0MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNj
21
- b20wHhcNMTEwMzAxMTkzMjA0WhcNMTIwMjI5MTkzMjA0WjBBMRMwEQYDVQQDDApj
22
- dm9ua2xlaXN0MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
23
- FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9y1uDfBvTfKE4
24
- tPGA5hbAav7pUtP8HRdBDLZOOks0+j0b1E4fUNglG4kdEBNpLk/ngVkPweUj8i5h
25
- oNVNRN2oxRw/4bSikOeNS3mpIqc/muDa2aMaO3ALtC9TrOIAZMx6+bbHZa4MeHwv
26
- AGAkrW8xV8FsHdD/yj3uAsEXFp6OdvCvVRQn2dRDF1nnPH62qeVPYrg+A+C/63Hn
27
- +8xd428nMeO6oOdKJpjJc7sBifW6dZbxZWU+x4eoQjIWpCMVGx4mB2LhRxA8I2AZ
28
- YEB4bdWLiQNLDW8BW18BALJRwSYGma6bQWeYp3BP+bYcg2Twqsj9l/byA/ad1arU
29
- 7toOPs9DAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
30
- BBSLpCugjo/9vnQB4ne51IOzvAEqEzANBgkqhkiG9w0BAQUFAAOCAQEAjNr9nF4C
31
- zVmcdovmY5ctUVhxi+iWZ6sApuEanzmZ4WL2ldAMam3vUWz9it66wN+uQuBt3HHW
32
- OAFBTKpFnrxwD24ZAxnetn6bphctGW/he8GyLInBdUkhq5W/Oz+Ca6WkMy/Ofm2v
33
- kN0NjJDThfqNTimd/YnyuXo0MSq6jJdv4x5g+Cd1GqIE9nJktDr+C3Bn2Kl0RU8k
34
- 0dJtwaemYW21gKzLDNJaREmmaEzceqCZawE52p4Ay2tMIGrZDE4lcq1TnGbM0YIN
35
- tg88OxjT6gj/ANHONv3pFs0TZs/LOTlpUoIstpNKnVxkz4Xut3XUsqfCzHUOBnoC
36
- DnOM3kD7rptG2g==
37
- -----END CERTIFICATE-----
38
-
39
- date: 2011-03-03 00:00:00 -05:00
40
- default_executable:
41
- dependencies: []
42
-
10
+ cert_chain: []
11
+ date: 2017-11-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "<"
18
+ - !ruby/object:Gem::Version
19
+ version: '3'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: '1.1'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "<"
28
+ - !ruby/object:Gem::Version
29
+ version: '3'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '1.1'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rack-test
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 0.6.2
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.6.2
47
+ - !ruby/object:Gem::Dependency
48
+ name: sinatra
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 1.3.4
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 1.3.4
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 2.14.1
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 2.14.1
43
75
  description: Encrypted session cookies for Rack
44
76
  email: cvonkleist at-a-place-called gmail.com
45
77
  executables: []
46
-
47
78
  extensions: []
48
-
49
- extra_rdoc_files:
79
+ extra_rdoc_files:
50
80
  - README.markdown
51
81
  - lib/encrypted_cookie.rb
52
- files:
82
+ files:
53
83
  - Manifest
54
84
  - README.markdown
55
85
  - Rakefile
56
86
  - encrypted_cookie.gemspec
57
87
  - lib/encrypted_cookie.rb
88
+ - lib/encrypted_cookie/encryptor.rb
58
89
  - spec/encrypted_cookie_spec.rb
59
- has_rdoc: true
60
90
  homepage: http://github.com/cvonkleist/encrypted_cookie
61
91
  licenses: []
62
-
92
+ metadata: {}
63
93
  post_install_message:
64
- rdoc_options:
65
- - --line-numbers
66
- - --inline-source
67
- - --title
94
+ rdoc_options:
95
+ - "--line-numbers"
96
+ - "--inline-source"
97
+ - "--title"
68
98
  - Encrypted_cookie
69
- - --main
99
+ - "--main"
70
100
  - README.markdown
71
- require_paths:
101
+ require_paths:
72
102
  - lib
73
- required_ruby_version: !ruby/object:Gem::Requirement
74
- none: false
75
- requirements:
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
76
105
  - - ">="
77
- - !ruby/object:Gem::Version
78
- hash: 3
79
- segments:
80
- - 0
81
- version: "0"
82
- required_rubygems_version: !ruby/object:Gem::Requirement
83
- none: false
84
- requirements:
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
85
110
  - - ">="
86
- - !ruby/object:Gem::Version
87
- hash: 11
88
- segments:
89
- - 1
90
- - 2
91
- version: "1.2"
111
+ - !ruby/object:Gem::Version
112
+ version: '1.2'
92
113
  requirements: []
93
-
94
114
  rubyforge_project: encrypted_cookie
95
- rubygems_version: 1.3.7
115
+ rubygems_version: 2.4.5.1
96
116
  signing_key:
97
- specification_version: 3
117
+ specification_version: 4
98
118
  summary: Encrypted session cookies for Rack
99
119
  test_files: []
100
-
data.tar.gz.sig DELETED
Binary file
metadata.gz.sig DELETED
Binary file