legacy-fernet 1.6.1

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.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fernet.gemspec
4
+ gemspec
@@ -0,0 +1,29 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ legacy-fernet (1.6.1)
5
+ multi_json
6
+ oj
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ diff-lcs (1.1.3)
12
+ multi_json (1.7.9)
13
+ oj (2.1.4)
14
+ rspec (2.11.0)
15
+ rspec-core (~> 2.11.0)
16
+ rspec-expectations (~> 2.11.0)
17
+ rspec-mocks (~> 2.11.0)
18
+ rspec-core (2.11.1)
19
+ rspec-expectations (2.11.3)
20
+ diff-lcs (~> 1.1.3)
21
+ rspec-mocks (2.11.3)
22
+
23
+ PLATFORMS
24
+ java
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ legacy-fernet!
29
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Harold Giménez
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,108 @@
1
+ # Fernet
2
+
3
+ [![Build Status](https://secure.travis-ci.org/hgmnz/fernet.png)](http://travis-ci.org/hgmnz/fernet)
4
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/hgmnz/fernet)
5
+
6
+ Fernet allows you to easily generate and verify **HMAC based authentication
7
+ tokens** for issuing API requests between remote servers. It also **encrypts**
8
+ data by default, so it can be used to transmit secure messages over the wire.
9
+
10
+ ![Fernet](http://f.cl.ly/items/2d0P3d26271O3p2v253u/photo.JPG)
11
+
12
+ Fernet is usually served as a *digestif* after a meal but may also be served
13
+ with coffee and espresso or mixed into coffee and espresso drinks.
14
+
15
+ Fernet about it!
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ gem 'fernet'
22
+
23
+ And then execute:
24
+
25
+ $ bundle
26
+
27
+ Or install it yourself as:
28
+
29
+ $ gem install fernet
30
+
31
+ ## Usage
32
+
33
+ Both server and client must share a secret.
34
+
35
+ You want to encode some data in the token as well, for example, an email
36
+ address can be used to verify it on the other end.
37
+
38
+ ```ruby
39
+ token = Fernet.generate(secret) do |generator|
40
+ generator.data = { email: 'harold@heroku.com' }
41
+ end
42
+ ```
43
+ On the server side, the receiver can use this token to verify whether it's
44
+ legit:
45
+
46
+ ```ruby
47
+ verified = Fernet.verify(secret, token) do |verifier|
48
+ verifier.data['email'] == 'harold@heroku.com'
49
+ end
50
+ ```
51
+
52
+ The `verified` variable will be true if:
53
+
54
+ * The email encoded in the token data is `harold@heroku.com`
55
+ * The token was generated in the last 60 seconds
56
+ * The secret used to generate the token matches
57
+
58
+ Otherwise, `verified` will be false, and you should deny the request with an
59
+ HTTP 401, for example.
60
+
61
+ The `Fernet.verify` method can be awkward if extracting the plain text data is
62
+ required. For this case, a `verifier` can be requested that makes that
63
+ use case more pleasent:
64
+
65
+ ```ruby
66
+ verifier = Fernet.verifier(secret, token)
67
+ if verifier.valid? # signature valid, TTL verified
68
+ operate_on(verifier.data) # the original, decrypted data
69
+ end
70
+ ```
71
+
72
+ The specs
73
+ ([spec/fernet_spec.rb](https://github.com/hgmnz/fernet/blob/master/spec/fernet_spec.rb))
74
+ have more usage examples.
75
+
76
+ ### Global configuration
77
+
78
+ It's possible to configure fernet via the `Configuration` class. Put this in an initializer:
79
+
80
+ ```ruby
81
+ # default values shown here
82
+ Fernet::Configuration.run do |config|
83
+ config.enforce_ttl = true
84
+ config.ttl = 60
85
+ config.encrypt = true
86
+ end
87
+ ```
88
+
89
+ ### Generating a secret
90
+
91
+ Generating appropriate secrets is beyond the scope of `Fernet`, but you should
92
+ generate it using `/dev/random` in a *nix. To generate a base64-encoded 256 bit
93
+ (32 byte) random sequence, try:
94
+
95
+ dd if=/dev/urandom bs=32 count=1 2>/dev/null | openssl base64
96
+
97
+ ### Attribution
98
+
99
+ This library was largely made possible by [Mr. Tom
100
+ Maher](http://twitter.com/#tmaher), who clearly articulated the mechanics
101
+ behind this process, and further found ways to make it
102
+ [more](https://github.com/hgmnz/fernet/commit/2bf0b4a66b49ef3fc92ef50708a2c8b401950fc2)
103
+ [secure](https://github.com/hgmnz/fernet/commit/051161d0afb0b41480734d84bc824bdbc7f9c563).
104
+
105
+ ## License
106
+
107
+ Fernet is copyright (c) Harold Giménez and is released under the terms of the
108
+ MIT License found in the LICENSE file.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/fernet/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Harold Giménez"]
6
+ gem.email = ["harold.gimenez@gmail.com"]
7
+ gem.description = %q{Delicious HMAC Digest(if) authentication and encryption}
8
+ gem.summary = %q{Easily generate and verify AES encrypted HMAC based authentication tokens}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "legacy-fernet"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Legacy::Fernet::VERSION
17
+
18
+ gem.add_dependency "oj"
19
+ gem.add_dependency "multi_json"
20
+
21
+ gem.add_development_dependency "rspec"
22
+ end
@@ -0,0 +1,27 @@
1
+ require 'fernet/version'
2
+ require 'fernet/generator'
3
+ require 'fernet/verifier'
4
+ require 'fernet/secret'
5
+ require 'fernet/configuration'
6
+
7
+ if RUBY_VERSION == '1.8.7'
8
+ require 'shim/base64'
9
+ end
10
+
11
+ Legacy::Fernet::Configuration.run
12
+
13
+ module Legacy::Fernet
14
+ def self.generate(secret, encrypt = Configuration.encrypt, &block)
15
+ Generator.new(secret, encrypt).generate(&block)
16
+ end
17
+
18
+ def self.verify(secret, token, encrypt = Configuration.encrypt, &block)
19
+ Verifier.new(secret, encrypt).verify_token(token, &block)
20
+ end
21
+
22
+ def self.verifier(secret, token, encrypt = Configuration.encrypt)
23
+ Verifier.new(secret, encrypt).tap do |v|
24
+ v.verify_token(token)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,39 @@
1
+ require 'singleton'
2
+ module Legacy::Fernet
3
+ class Configuration
4
+ include Singleton
5
+
6
+ # Whether to enforce a message TTL
7
+ # (true or false)
8
+ attr_accessor :enforce_ttl
9
+
10
+ # How long messages are considered valid to the verifier
11
+ # (an integer in seconds)
12
+ attr_accessor :ttl
13
+
14
+ # Whether to encrypt the payload
15
+ # (true or false)
16
+ attr_accessor :encrypt
17
+
18
+ def self.run
19
+ self.instance.enforce_ttl = true
20
+ self.instance.ttl = 60
21
+ self.instance.encrypt = true
22
+ yield self.instance if block_given?
23
+ end
24
+
25
+ class << self
26
+ def method_missing(method)
27
+ if self.instance.respond_to?(method)
28
+ self.instance.send(method)
29
+ else
30
+ super
31
+ end
32
+ end
33
+
34
+ def respond_to?(method)
35
+ self.instance.respond_to?(method) || super
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,71 @@
1
+ require 'base64'
2
+ require 'multi_json'
3
+ require 'openssl'
4
+ require 'date'
5
+
6
+ module Legacy::Fernet
7
+ class Generator
8
+ attr_accessor :data, :payload
9
+
10
+ def initialize(secret, encrypt)
11
+ @secret = Secret.new(secret, encrypt)
12
+ @encrypt = encrypt
13
+ @payload = ''
14
+ @data = {}
15
+ end
16
+
17
+ def generate
18
+ yield self if block_given?
19
+ data.merge!(:issued_at => DateTime.now)
20
+
21
+ if encrypt?
22
+ iv = encrypt_data!
23
+ @payload = "#{base64(data)}|#{base64(iv)}"
24
+ else
25
+ @payload = base64(MultiJson.dump(data))
26
+ end
27
+
28
+ mac = OpenSSL::HMAC.hexdigest('sha256', payload, signing_key)
29
+ "#{payload}|#{mac}"
30
+ end
31
+
32
+ def inspect
33
+ "#<Legacy::Fernet::Generator @secret=[masked] @data=#{@data.inspect}>"
34
+ end
35
+ alias to_s inspect
36
+
37
+ def data
38
+ @data ||= {}
39
+ end
40
+
41
+ private
42
+ attr_reader :secret
43
+
44
+ def encrypt_data!
45
+ cipher = OpenSSL::Cipher.new('AES-128-CBC')
46
+ cipher.encrypt
47
+ iv = cipher.random_iv
48
+ cipher.iv = iv
49
+ cipher.key = encryption_key
50
+ @data = cipher.update(MultiJson.dump(data)) + cipher.final
51
+ iv
52
+ end
53
+
54
+ def base64(chars)
55
+ Base64.urlsafe_encode64(chars)
56
+ end
57
+
58
+ def encryption_key
59
+ @secret.encryption_key
60
+ end
61
+
62
+ def signing_key
63
+ @secret.signing_key
64
+ end
65
+
66
+ def encrypt?
67
+ @encrypt
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,20 @@
1
+ module Legacy::Fernet
2
+ class Secret
3
+ def initialize(secret, encrypt)
4
+ @secret = secret
5
+ @encrypt = encrypt
6
+ end
7
+
8
+ def encryption_key
9
+ @secret.slice(@secret.size/2, @secret.size)
10
+ end
11
+
12
+ def signing_key
13
+ if @encrypt
14
+ @secret.slice(0, @secret.size/2)
15
+ else
16
+ @secret
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,102 @@
1
+ require 'base64'
2
+ require 'multi_json'
3
+ require 'openssl'
4
+ require 'date'
5
+
6
+ module Legacy::Fernet
7
+ class Verifier
8
+ attr_reader :token, :data
9
+ attr_accessor :ttl, :enforce_ttl
10
+
11
+ def initialize(secret, decrypt)
12
+ @secret = Secret.new(secret, decrypt)
13
+ @decrypt = decrypt
14
+ @ttl = Configuration.ttl
15
+ @enforce_ttl = Configuration.enforce_ttl
16
+ end
17
+
18
+ def verify_token(token)
19
+ @token = token
20
+ deconstruct
21
+
22
+ if block_given?
23
+ custom_verification = yield self
24
+ else
25
+ custom_verification = true
26
+ end
27
+
28
+ @valid = signatures_match? && token_recent_enough? && custom_verification
29
+ end
30
+
31
+ def valid?
32
+ @valid
33
+ end
34
+
35
+ def inspect
36
+ "#<Legacy::Fernet::Verifier @secret=[masked] @token=#{@token} @data=#{@data.inspect} @ttl=#{@ttl}>"
37
+ end
38
+ alias to_s inspect
39
+
40
+ private
41
+ attr_reader :secret
42
+
43
+ def deconstruct
44
+ parts = @token.split('|')
45
+ if decrypt?
46
+ encrypted_data, iv, @received_signature = *parts
47
+ @data = MultiJson.load(decrypt!(encrypted_data, Base64.urlsafe_decode64(iv)))
48
+ signing_blob = "#{encrypted_data}|#{iv}"
49
+ else
50
+ encoded_data, @received_signature = *parts
51
+ signing_blob = encoded_data
52
+ @data = MultiJson.load(Base64.urlsafe_decode64(encoded_data))
53
+ end
54
+ @regenerated_mac = OpenSSL::HMAC.hexdigest('sha256', signing_blob, signing_key)
55
+ end
56
+
57
+ def token_recent_enough?
58
+ if enforce_ttl?
59
+ good_till = DateTime.parse(data['issued_at']) + (ttl.to_f / 24 / 60 / 60)
60
+ good_till > now
61
+ else
62
+ true
63
+ end
64
+ end
65
+
66
+ def signatures_match?
67
+ regenerated_bytes = @regenerated_mac.bytes.to_a
68
+ received_bytes = @received_signature.bytes.to_a
69
+ received_bytes.inject(0) do |accum, byte|
70
+ accum |= byte ^ regenerated_bytes.shift
71
+ end.zero?
72
+ end
73
+
74
+ def decrypt!(encrypted_data, iv)
75
+ decipher = OpenSSL::Cipher.new('AES-128-CBC')
76
+ decipher.decrypt
77
+ decipher.iv = iv
78
+ decipher.key = encryption_key
79
+ decipher.update(Base64.urlsafe_decode64(encrypted_data)) + decipher.final
80
+ end
81
+
82
+ def encryption_key
83
+ @secret.encryption_key
84
+ end
85
+
86
+ def signing_key
87
+ @secret.signing_key
88
+ end
89
+
90
+ def decrypt?
91
+ @decrypt
92
+ end
93
+
94
+ def enforce_ttl?
95
+ @enforce_ttl
96
+ end
97
+
98
+ def now
99
+ DateTime.now
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,5 @@
1
+ module Legacy
2
+ module Fernet
3
+ VERSION = "1.6.1"
4
+ end
5
+ end
@@ -0,0 +1,21 @@
1
+ Base64.class_eval do
2
+ def strict_encode64(bin)
3
+ encode64(bin).tr("\n",'')
4
+ end
5
+
6
+ def strict_decode64(str)
7
+ unless str.include?("\n")
8
+ decode64(str)
9
+ else
10
+ raise(ArgumentError,"invalid base64")
11
+ end
12
+ end
13
+
14
+ def urlsafe_encode64(bin)
15
+ strict_encode64(bin).tr("+/", "-_")
16
+ end
17
+
18
+ def urlsafe_decode64(str)
19
+ strict_decode64(str.tr("-_", "+/"))
20
+ end
21
+ end
@@ -0,0 +1,164 @@
1
+ require 'spec_helper'
2
+ require 'fernet'
3
+
4
+ describe Legacy::Fernet do
5
+ after { Legacy::Fernet::Configuration.run }
6
+
7
+ let(:token_data) do
8
+ { :email => 'harold@heroku.com', :id => '123', :arbitrary => 'data' }
9
+ end
10
+
11
+ let(:secret) { 'JrdICDH6x3M7duQeM8dJEMK4Y5TkBIsYDw1lPy35RiY=' }
12
+ let(:bad_secret) { 'badICDH6x3M7duQeM8dJEMK4Y5TkBIsYDw1lPy35RiY=' }
13
+
14
+ it 'can verify tokens it generates' do
15
+ token = Legacy::Fernet.generate(secret) do |generator|
16
+ generator.data = token_data
17
+ end
18
+
19
+ expect(
20
+ Legacy::Fernet.verify(secret, token) do |verifier|
21
+ verifier.data['email'] == 'harold@heroku.com'
22
+ end
23
+ ).to be_true
24
+ end
25
+
26
+ it 'fails with a bad secret' do
27
+ token = Legacy::Fernet.generate(secret) do |generator|
28
+ generator.data = token_data
29
+ end
30
+
31
+ expect(
32
+ Legacy::Fernet.verify(bad_secret, token) do |verifier|
33
+ verifier.data['email'] == 'harold@heroku.com'
34
+ end
35
+ ).to be_false
36
+ end
37
+
38
+ it 'fails with a bad custom verification' do
39
+ token = Legacy::Fernet.generate(secret) do |generator|
40
+ generator.data = { :email => 'harold@heroku.com' }
41
+ end
42
+
43
+ expect(
44
+ Legacy::Fernet.verify(secret, token) do |verifier|
45
+ verifier.data['email'] == 'lol@heroku.com'
46
+ end
47
+ ).to be_false
48
+ end
49
+
50
+ it 'fails if the token is too old' do
51
+ token = Legacy::Fernet.generate(secret) do |generator|
52
+ generator.data = token_data
53
+ end
54
+
55
+ expect(
56
+ Legacy::Fernet.verify(secret, token) do |verifier|
57
+ verifier.ttl = 1
58
+
59
+ def verifier.now
60
+ now = DateTime.now
61
+ DateTime.new(now.year, now.month, now.day, now.hour,
62
+ now.min, now.sec + 2, now.offset)
63
+ end
64
+ true
65
+ end
66
+ ).to be_false
67
+ end
68
+
69
+ it 'verifies without a custom verification' do
70
+ token = Legacy::Fernet.generate(secret) do |generator|
71
+ generator.data = token_data
72
+ end
73
+
74
+ expect(Legacy::Fernet.verify(secret, token)).to be_true
75
+ end
76
+
77
+ it 'can ignore TTL enforcement' do
78
+ token = Legacy::Fernet.generate(secret) do |generator|
79
+ generator.data = token_data
80
+ end
81
+
82
+ expect(
83
+ Legacy::Fernet.verify(secret, token) do |verifier|
84
+ def verifier.now
85
+ Time.now + 99999999999
86
+ end
87
+ verifier.enforce_ttl = false
88
+ true
89
+ end
90
+ ).to be_true
91
+ end
92
+
93
+ it 'can ignore TTL enforcement via global config' do
94
+ Legacy::Fernet::Configuration.run do |config|
95
+ config.enforce_ttl = false
96
+ end
97
+
98
+ token = Legacy::Fernet.generate(secret) do |generator|
99
+ generator.data = token_data
100
+ end
101
+
102
+ expect(
103
+ Legacy::Fernet.verify(secret, token) do |verifier|
104
+ def verifier.now
105
+ Time.now + 99999999999
106
+ end
107
+ true
108
+ end
109
+ ).to be_true
110
+ end
111
+
112
+ it 'generates without custom data' do
113
+ token = Legacy::Fernet.generate(secret)
114
+
115
+ expect(Legacy::Fernet.verify(secret, token)).to be_true
116
+ end
117
+
118
+ it 'can encrypt the payload' do
119
+ token = Legacy::Fernet.generate(secret, true) do |generator|
120
+ generator.data['password'] = 'password1'
121
+ end
122
+
123
+ expect(Base64.decode64(token)).not_to match /password1/
124
+
125
+ Legacy::Fernet.verify(secret, token) do |verifier|
126
+ expect(verifier.data['password']).to eq('password1')
127
+ end
128
+ end
129
+
130
+ it 'does not encrypt when asked nicely' do
131
+ token = Legacy::Fernet.generate(secret, false) do |generator|
132
+ generator.data['password'] = 'password1'
133
+ end
134
+
135
+ expect(Base64.decode64(token)).to match /password1/
136
+
137
+ Legacy::Fernet.verify(secret, token, false) do |verifier|
138
+ expect(verifier.data['password']).to eq('password1')
139
+ end
140
+ end
141
+
142
+ it 'can disable encryption via global configuration' do
143
+ Legacy::Fernet::Configuration.run { |c| c.encrypt = false }
144
+ token = Legacy::Fernet.generate(secret) do |generator|
145
+ generator.data['password'] = 'password1'
146
+ end
147
+
148
+ expect(Base64.decode64(token)).to match /password1/
149
+
150
+ Legacy::Fernet.verify(secret, token) do |verifier|
151
+ expect(verifier.data['password']).to eq('password1')
152
+ end
153
+ end
154
+
155
+ it 'returns the unencrypted message upon verify' do
156
+ token = Legacy::Fernet.generate(secret) do |generator|
157
+ generator.data['password'] = 'password1'
158
+ end
159
+
160
+ verifier = Legacy::Fernet.verifier(secret, token)
161
+ expect(verifier.valid?).to be_true
162
+ expect(verifier.data['password']).to eq('password1')
163
+ end
164
+ end
@@ -0,0 +1,21 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ config.order = 'random'
17
+
18
+ config.expect_with :rspec do |c|
19
+ c.syntax = :expect
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: legacy-fernet
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.6.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Harold Giménez
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-08-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: oj
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: multi_json
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Delicious HMAC Digest(if) authentication and encryption
63
+ email:
64
+ - harold.gimenez@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - Gemfile
70
+ - Gemfile.lock
71
+ - LICENSE
72
+ - README.md
73
+ - Rakefile
74
+ - fernet.gemspec
75
+ - lib/fernet.rb
76
+ - lib/fernet/configuration.rb
77
+ - lib/fernet/generator.rb
78
+ - lib/fernet/secret.rb
79
+ - lib/fernet/verifier.rb
80
+ - lib/fernet/version.rb
81
+ - lib/shim/base64.rb
82
+ - spec/fernet_spec.rb
83
+ - spec/spec_helper.rb
84
+ homepage: ''
85
+ licenses: []
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 1.8.23
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: Easily generate and verify AES encrypted HMAC based authentication tokens
108
+ test_files:
109
+ - spec/fernet_spec.rb
110
+ - spec/spec_helper.rb