rjharmon-strongbox 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2009 Joseph A. Ilacqua, Jr
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,271 @@
1
+ h1. Strongbox
2
+
3
+ Strongbox provides Public Key Encryption for ActiveRecord. By using a public key
4
+ sensitive information can be encrypted and stored automatically. Once stored, the
5
+ private key and password are required to access the information.
6
+
7
+ Because the largest amount of data that can practically be encrypted with a 2048-bit
8
+ public key is 245 bytes, by default Strongbox uses a two layer approach. First it
9
+ encrypts the attribute using symmetric encryption with a randomly generated key and
10
+ initialization vector (IV) (which can just be thought of as a second key), then it
11
+ encrypts those with the public key.
12
+
13
+ Strongbox stores the encrypted attribute in a database column by the same name, i.e.
14
+ if you tell Strongbox to encrypt "secret" then it will be store in "secret" in the
15
+ database, just as the unencrypted attribute would have been. If symmetric encryption
16
+ is used (the default) two additional columns "secret_key" and "secret_iv" are needed
17
+ as well.
18
+
19
+ The attribute is automatically and immediately encrypted simply by setting it:
20
+
21
+ user.secret = "Shhhhhhh..."
22
+
23
+ and decrypted by calling the "decrypt" method with the private key password.
24
+
25
+ plain_text = user.secret.decrypt 'letmein'
26
+
27
+ The password for the private key can be empty if you are protecting the key through a
28
+ different method. In that case, provide the empty string '' to decrypt() in order to
29
+ decrypt the data.
30
+
31
+ This fork of Strongbox is also able to perform symmetric-only encryption. If you
32
+ do this, be sure that you're protecting the symmetric key. One application of this is
33
+ for encrypting data to a private password known by the user. See below for more options.
34
+
35
+ h2. Quick Start
36
+
37
+ In your model:
38
+
39
+ bc. class User < ActiveRecord::Base
40
+ encrypt_with_public_key :secret,
41
+ :key_pair => File.join(RAILS_ROOT,'config','keypair.pem')
42
+ end
43
+
44
+ In your migrations:
45
+
46
+ bc. class AddSecretColumnsToUser < ActiveRecord::Migration
47
+ def self.up
48
+ add_column :users, :secret, :binary
49
+ add_column :users, :secret_key, :binary
50
+ add_column :users, :secret_iv, :binary
51
+ end
52
+ def self.down
53
+ remove_column :users, :secret
54
+ remove_column :users, :secret_key
55
+ remove_column :users, :secret_iv
56
+ end
57
+ end
58
+
59
+ Generate a key pair:
60
+
61
+ (Choose a strong password.)
62
+
63
+ bc. openssl genrsa -des3 -out config/private.pem 2048
64
+ openssl rsa -in config/private.pem -out config/public.pem -outform PEM -pubout
65
+ cat config/private.pem config/public.pem >> config/keypair.pem
66
+
67
+ In your views and forms you don't need to do anything special to encrypt data. To
68
+ decrypt call:
69
+
70
+ bc. user.secret.decrypt 'password'
71
+
72
+ h2. Gem installation (Rails 2.1+)
73
+
74
+ In config/environment.rb:
75
+
76
+ bc. config.gem "strongbox"
77
+
78
+ h2. Usage
79
+
80
+ _encrypt_with_public_key_ sets up the attribute it's called on for automatic
81
+ encryption. It's simplest form is:
82
+
83
+ bc. class User < ActiveRecord::Base
84
+ encrypt_with_public_key :secret,
85
+ :key_pair => File.join(RAILS_ROOT,'config','keypair.pem')
86
+ end
87
+
88
+ Which will encrypt the attribute "secret". The attribute will be encrypted using
89
+ symmetric encryption with an automatically generated key and IV encrypted using the
90
+ public key. This requires three columns in the database "secret", "secret_key", and
91
+ "secret_iv" (see below).
92
+
93
+ Options to encrypt_with_public_key are:
94
+
95
+ :public_key - Path to the public key file. Overrides :keypair.
96
+
97
+ :private_key - Path to the private key file. Overrides :keypair.
98
+
99
+ :keypair - Path to a file containing both the public and private keys.
100
+
101
+ :symmetric :always/:never - Encrypt the date using symmetric encryption. The public
102
+ key is used to encrypt an automatically generated key and IV. This allows for large
103
+ amounts of data to be encrypted. The size of data that can be encrypted directly with
104
+ the public is limit to key size (in bytes) - 11. So a 2048 key can encrypt *245 bytes*. Defaults to :always
105
+
106
+ :symmetric_cipher - Cipher to use for symmetric encryption. Defaults to *'aes-256-cbc'*. Other ciphers support by OpenSSL may be used.
107
+
108
+ :base64 true/false - Use Base64 encoding to convert encrypted data to text. Use when
109
+ binary save data storage is not available. Defaults to *false*
110
+
111
+ :padding - Method used to pad data encrypted with the public key. Defaults to
112
+ RSA_PKCS1_PADDING. The default should be fine unless you are dealing with legacy
113
+ data.
114
+
115
+ :encrypt_iv true/false - Default is true for backward compatibility, but it is not
116
+ necessary to encrypt the initialization vector to maintain security. For first-time
117
+ installations, you might choose to set this to false, which cuts the encryption and
118
+ decryption overhead approximately in half. There is currently no method for
119
+ migrating encrypted iv's to clear-text iv's, but you could add a second set of columns
120
+ with a different configuration and write a script that decrypts values from one encrypted
121
+ column and stores them into to the second decrypted column.
122
+
123
+
124
+ For example, encrypting a small attribute, providing only the public key for extra
125
+ security, and Base64 encoding the encrypted data:
126
+
127
+ bc. class User < ActiveRecord::Base
128
+ validates_length_of :pin_code, :is => 4
129
+ encrypt_with_public_key :pin_code,
130
+ :symmetric => :never,
131
+ :base64 => true,
132
+ :public_key => File.join(RAILS_ROOT,'config','public.pem')
133
+ end
134
+
135
+ h2. Key Generation
136
+
137
+ Generate a key pair:
138
+
139
+ bc. openssl genrsa -des3 -out config/private.pem 2048
140
+ Generating RSA private key, 2048 bit long modulus
141
+ ......+++
142
+ .+++
143
+ e is 65537 (0x10001)
144
+ Enter pass phrase for config/private.pem:
145
+ Verifying - Enter pass phrase for config/private.pem:
146
+
147
+ and extract the the public key:
148
+
149
+ bc. openssl rsa -in config/private.pem -out config/public.pem -outform PEM -pubout
150
+ Enter pass phrase for config/private.pem:
151
+ writing RSA key
152
+
153
+ If you are going to leave the private key installed it's easiest to create a single
154
+ key pair file:
155
+
156
+ bc. cat config/private.pem config/public.pem >> config/keypair.pem
157
+
158
+ Or, for added security, store the private key file else where, leaving only the public key.
159
+
160
+ h2. Table Creation
161
+
162
+ In it's default configuration Strongbox requires three columns, one the encrypted
163
+ data, one for the encrypted symmetric key, and one for the encrypted symmetric IV. If
164
+ symmetric encryption is disabled then only the columns for the data being encrypted
165
+ is needed.
166
+
167
+ If your underlying database allows, use the *binary* column type. If you must store
168
+ your data in text format be sure to enable Base64 encoding and to use the *text*
169
+ column type. If you use a _string_ column and encrypt anything greater than 186
170
+ bytes (245 bytes if you don't enable Base64 encoding) *your data will be lost*.
171
+
172
+ h2. Validation
173
+
174
+ Because Strongbox immediately encrypts the data as you assign it into the model,
175
+ the amount of validation that can be done is minimal, being limited to
176
+ validates_size_of and validates_presence_of.
177
+
178
+ If you require additional validation for your encrypted columns, this should be done
179
+ before assigning into encrypted attributes. That, or you might want to contribute a
180
+ patch that delays the encryption step until right before save.
181
+
182
+ h2. Symmetric Encryption
183
+
184
+ h3. Background
185
+
186
+ Asymmetric encryption is generally far preferred over symmetric-only encryption.
187
+ Being able to physically separate and protect the private decryption key from the
188
+ public encryption key creates a level of potential security unmatchable with
189
+ symmetric encryption, which is reversible using the single encryption key.
190
+
191
+ However, symmetric keys can be useful in certain circumstances - for example the
192
+ combined symmetric/asymmetric encryption provided by default with
193
+ _encrypt_with_public_key_. Other advanced examples include:
194
+
195
+ * Encrypt data to a PIN code known only to the user (retrieve it only when they re-type their PIN)
196
+
197
+ * Encrypt a PIN code with public key, then use the PIN to symmetrically encrypt other data, so
198
+ that it can be retrieved directly by the user but not by an attacker. Combined with pubkey
199
+ encryption for the same data, much flexibility is gained with a minimum of risk exposure - though
200
+ it comes with a tradeoff: increased code complexity.
201
+
202
+ h3. Implementing Symmetric Encryption
203
+
204
+ If you don't understand the caveats above, please re-read them. Then, if you are
205
+ prepared to do symmetric encryption, use _encrypt_with_symmetric_key_:
206
+
207
+ bc. class User < ActiveRecord::Base
208
+ validates_length_of :pin_code, :is => 4
209
+ encrypt_with_symmetric_key :some_data, :encrypt_iv => false, :key_proc => :pin_key
210
+ attr_accessor :pin_key
211
+ end
212
+
213
+ All options are the same as for pubkey encryption, except that no keys may be specified.
214
+ Additionally, :encrypt_iv must be set to false, and the :key_proc must be specified as a
215
+ symbol referring to a function which will return the symmetric key.
216
+
217
+ h3. Implementing the symmetric-key function
218
+
219
+ Two examples should demonstrate the use of a function that returns symmetric keys. They
220
+ correspond to the two use cases mentioned above.
221
+
222
+ Encrypting with a key not stored on the server: This is easily implemented by creating
223
+ an attr_accessor on the model having the encrypted field.
224
+
225
+ bc. class User < ActiveRecord::Base
226
+ encrypt_with_symmetric_key :some_data, :encrypt_iv => false, :key_proc => :pin_key
227
+ attr_accessor :pin_key
228
+ end
229
+
230
+ In your controller, put the key into the model prior to storing or retrieving encrypted data.
231
+
232
+ In the second example, we store the user's PIN, encrypted asymmetrically. To encrypt
233
+ data to the PIN code, we go inside the security perimeter where we have the private key;
234
+ decrypt the PIN, then set it, possibly using the attr_accessor method, prior to encrypting
235
+ the symmetric data.
236
+
237
+ Decryption for user-facing content is done the same way as in the first example.
238
+
239
+ Another method of implementing the :key_proc is as follows:
240
+
241
+ bc. attr_writer :pin_key
242
+ def pin_key
243
+ @pin_key || self.pin.decrypt('password')
244
+ end
245
+
246
+ h2. Security Caveats
247
+
248
+ If you don't encrypt your data, then an attacker only needs to steal that data to get
249
+ your secrets.
250
+
251
+ If encrypt your data using symmetric encrypts and a stored key, then the attacker
252
+ needs the data and the key stored on the server.
253
+
254
+ If you use public key encryption, the attacker needs the data, the private key, and
255
+ the password. This means the attacker has to sniff the password somehow, so that's
256
+ what you need to protect against.
257
+
258
+ h2. Authors
259
+
260
+ Spike Ilacqua
261
+
262
+ h2. Contributors
263
+
264
+ Randy Harmon
265
+
266
+ h2. Thanks
267
+
268
+ Strongbox's implementation drew inspiration from Thoughtbot's Paperclip gem
269
+ http://www.thoughtbot.com/projects/paperclip
270
+
271
+
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ $LOAD_PATH << File.join(File.dirname(__FILE__), 'lib')
6
+ require 'strongbox'
7
+
8
+ desc 'Default: run tests.'
9
+ task :default => :test
10
+
11
+ desc 'Test the strongbox gem.'
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << 'lib' << 'profile'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = true
16
+ end
17
+
18
+ desc 'Generate documentation for the strongbox gem.'
19
+ Rake::RDocTask.new(:rdoc) do |rdoc|
20
+ rdoc.rdoc_dir = 'doc'
21
+ rdoc.title = 'Strongbox'
22
+ rdoc.options << '--line-numbers' << '--inline-source'
23
+ rdoc.rdoc_files.include('README*')
24
+ rdoc.rdoc_files.include('lib/**/*.rb')
25
+ end
26
+
27
+ spec = Gem::Specification.new do |s|
28
+ s.name = "strongbox"
29
+ s.version = Strongbox::VERSION
30
+ s.summary = "Secures ActiveRecord fields with public key encryption."
31
+ s.authors = ["Spike Ilacqua"]
32
+ s.email = "spike@stuff-things.net"
33
+ s.homepage = "http://stuff-things.net/strongbox"
34
+ s.files = FileList["[A-Z]*", "init.rb", "{lib,rails}/**/*"]
35
+ s.add_development_dependency 'thoughtbot-shoulda'
36
+ end
37
+
38
+ desc "Generate a gemspec file for GitHub"
39
+ task :gemspec do
40
+ File.open("#{spec.name}.gemspec", 'w') do |f|
41
+ f.write spec.to_yaml
42
+ end
43
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'strongbox'
@@ -0,0 +1,190 @@
1
+ module Strongbox
2
+ # The Lock class encrypts and decrypts the protected attribute. It
3
+ # automatically encrypts the data when set and decrypts it when the private
4
+ # key password is provided.
5
+ class Lock
6
+
7
+ def initialize name, instance, options = {}
8
+ @name = name
9
+ @instance = instance
10
+
11
+ @size = nil
12
+
13
+ options = Strongbox.options.merge(options)
14
+
15
+ @is_empty = true if @instance[@name].blank?
16
+
17
+ @base64 = options[:base64]
18
+ @public_key = options[:public_key] || options[:key_pair]
19
+ @private_key = options[:private_key] || options[:key_pair]
20
+ @padding = options[:padding]
21
+ @symmetric = options[:symmetric]
22
+ @symmetric_cipher = options[:symmetric_cipher]
23
+ @symmetric_key = options[:symmetric_key] || "#{name}_key"
24
+ @symmetric_iv = options[:symmetric_iv] || "#{name}_iv"
25
+ @key_proc = options[:key_proc]
26
+ @encrypt_iv = options[:encrypt_iv]
27
+ if @symmetric == :only
28
+ if @encrypt_iv
29
+ raise ArgumentError, ":encrypt_iv should be set to false for :symmetric => :only encryption, since encrypting the iv requires a pubkey"
30
+ end
31
+ if @public_key
32
+ raise ArgumentError, ":public_key, :private_key and :key_pair are not used with :symmetric => :only"
33
+ end
34
+ unless @key_proc
35
+ raise ArgumentError, ":key_proc option is required. This option specifies a proc or a symbol of a method on the instance, which will return a key used for the symmetric cypher."
36
+ end
37
+ else
38
+ if @key_proc
39
+ raise ArgumentError, ":key_proc is valid only when :symmetric => :only is specified, or when using encrypt_with_symmetric_key()"
40
+ end
41
+ end
42
+ end
43
+
44
+ def encrypt plaintext
45
+
46
+ unless @public_key or @symmetric == :only
47
+ raise StrongboxError.new("#{@instance.class} model does not have public key_file")
48
+ end
49
+ if !plaintext.blank?
50
+ @is_empty = false
51
+ @size = plaintext.size # For validations
52
+ # Using a blank password in OpenSSL::PKey::RSA.new prevents reading
53
+ # the private key if the file is a key pair
54
+ public_key = get_rsa_key(@public_key,"")
55
+ if @symmetric == :always or @symmetric == :only
56
+ cipher = OpenSSL::Cipher::Cipher.new(@symmetric_cipher)
57
+ cipher.encrypt
58
+
59
+ cipher.key = symmetric_key = case @key_proc
60
+ when Proc
61
+ @key_proc.call( @instance )
62
+ when Symbol
63
+ @instance.send( @key_proc )
64
+ else
65
+ cipher.random_key
66
+ end
67
+ cipher.iv = symmetric_iv = cipher.random_iv
68
+
69
+ ciphertext = cipher.update(plaintext)
70
+ ciphertext << cipher.final
71
+ unless @symmetric == :only
72
+ encrypted_key = public_key.public_encrypt(symmetric_key,@padding)
73
+ end
74
+ if @encrypt_iv
75
+ encrypted_iv = public_key.public_encrypt(symmetric_iv,@padding)
76
+ end
77
+ if @base64
78
+ unless @symmetric == :only
79
+ encrypted_key = Base64.encode64(encrypted_key)
80
+ end
81
+ encrypted_iv = Base64.encode64(encrypted_iv)
82
+ end
83
+ unless @symmetric == :only
84
+ @instance[@symmetric_key] = encrypted_key
85
+ end
86
+ if @encrypt_iv
87
+ @instance[@symmetric_iv] = encrypted_iv
88
+ else
89
+ @instance[@symmetric_iv] = symmetric_iv
90
+ end
91
+ else
92
+ ciphertext = public_key.public_encrypt(plaintext,@padding)
93
+ end
94
+ ciphertext = Base64.encode64(ciphertext) if @base64
95
+ @instance[@name] = ciphertext
96
+ else
97
+ @size = 0
98
+ @instance[@name] = ""
99
+ @is_empty = true
100
+ end
101
+ end
102
+
103
+ # Given the private key password decrypts the attribute. Will raise
104
+ # OpenSSL::PKey::RSAError if the password is wrong.
105
+
106
+ def decrypt password = nil
107
+ return "" if @is_empty
108
+ # Given a private key and a nil password OpenSSL::PKey::RSA.new() will
109
+ # *prompt* for a password, we default to an empty string to avoid that.
110
+ ciphertext = @instance[@name]
111
+ return nil if ciphertext.nil?
112
+ return "" if ciphertext.empty?
113
+
114
+ return "*encrypted*" if password.nil? and ! @key_proc
115
+ unless @private_key or @symmetric == :only
116
+ raise StrongboxError.new("#{@instance.class} model does not have private key_file")
117
+ end
118
+
119
+ if ciphertext
120
+ ciphertext = Base64.decode64(ciphertext) if @base64
121
+ private_key = get_rsa_key(@private_key,password)
122
+
123
+ if @symmetric == :always || @symmetric == :only
124
+ symmetric_key = case @key_proc
125
+ when Proc
126
+ @key_proc.call( @instance )
127
+ when Symbol
128
+ @instance.send( @key_proc )
129
+ else
130
+ @instance[@symmetric_key]
131
+ end
132
+ symmetric_iv = @instance[@symmetric_iv]
133
+
134
+ if @base64
135
+ if @symmetric == :always
136
+ symmetric_key = Base64.decode64(symmetric_key)
137
+ end
138
+ symmetric_iv = Base64.decode64(symmetric_iv)
139
+ end
140
+ cipher = OpenSSL::Cipher::Cipher.new(@symmetric_cipher)
141
+ cipher.decrypt
142
+ cipher.key = if @symmetric == :only
143
+ symmetric_key
144
+ else
145
+ private_key.private_decrypt(symmetric_key,@padding)
146
+ end
147
+ if @encrypt_iv
148
+ cipher.iv = private_key.private_decrypt(symmetric_iv,@padding)
149
+ else
150
+ cipher.iv = symmetric_iv
151
+ end
152
+
153
+ plaintext = cipher.update(ciphertext)
154
+ plaintext << cipher.final
155
+ else
156
+ plaintext = private_key.private_decrypt(ciphertext,@padding)
157
+ end
158
+ else
159
+ nil
160
+ end
161
+ end
162
+
163
+ def to_s
164
+ decrypt
165
+ end
166
+
167
+ # Needed for validations
168
+ def blank?
169
+ @instance[@name].blank?
170
+ end
171
+
172
+ def nil?
173
+ @instance[@name].nil?
174
+ end
175
+
176
+ def size
177
+ @size
178
+ end
179
+
180
+ private
181
+ def get_rsa_key(key,password = '')
182
+ return nil unless key
183
+ return key if key.is_a?(OpenSSL::PKey::RSA)
184
+ if key !~ /^-----BEGIN RSA/
185
+ key = File.read(key)
186
+ end
187
+ return OpenSSL::PKey::RSA.new(key,password)
188
+ end
189
+ end
190
+ end
data/lib/strongbox.rb ADDED
@@ -0,0 +1,85 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+
4
+ require 'strongbox/lock'
5
+
6
+ module Strongbox
7
+
8
+ VERSION = "0.3.0"
9
+
10
+ RSA_PKCS1_PADDING = OpenSSL::PKey::RSA::PKCS1_PADDING
11
+ RSA_SSLV23_PADDING = OpenSSL::PKey::RSA::SSLV23_PADDING
12
+ RSA_NO_PADDING = OpenSSL::PKey::RSA::NO_PADDING
13
+ RSA_PKCS1_OAEP_PADDING = OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING
14
+
15
+ class << self
16
+ # Provides for setting the default options for Strongbox
17
+ def options
18
+ @options ||= {
19
+ :base64 => false,
20
+ :symmetric => :always,
21
+ :padding => RSA_PKCS1_PADDING,
22
+ :encrypt_iv => true,
23
+ :symmetric_cipher => 'aes-256-cbc'
24
+ }
25
+ end
26
+
27
+ def included base #:nodoc:
28
+ base.extend ClassMethods
29
+ end
30
+ end
31
+
32
+ class StrongboxError < StandardError #:nodoc:
33
+ end
34
+
35
+ module ClassMethods
36
+ # +encrypt_with_public_key+ gives the class it is called on an attribute that
37
+ # when assigned is automatically encrypted using a public key. This allows the
38
+ # unattended encryption of data, without exposing the information need to decrypt
39
+ # it (as would be the case when using symmetric key encryption alone). Small
40
+ # amounts of data may be encrypted directly with the public key. Larger data is
41
+ # encrypted using symmetric encryption. The encrypted data is stored in the
42
+ # database column of the same name as the attibute. If symmetric encryption is
43
+ # used (the default) additional column are need to store the generated password
44
+ # and IV.
45
+ def encrypt_with_public_key(name, options = {})
46
+ strongbox_encryption( name, options )
47
+ end
48
+
49
+ def encrypt_with_symmetric_key( name, options = {})
50
+ options.merge!( :symmetric => :only )
51
+ strongbox_encryption( name, options )
52
+ end
53
+
54
+ def strongbox_encryption( name, options )
55
+ include InstanceMethods
56
+
57
+ class_inheritable_reader :lock_options
58
+ write_inheritable_attribute(:lock_options, {}) if lock_options.nil?
59
+
60
+
61
+ lock_options[name] = options.symbolize_keys.reverse_merge Strongbox.options
62
+
63
+ define_method name do
64
+ lock_for(name)
65
+ end
66
+
67
+ define_method "#{name}=" do | plaintext |
68
+ lock_for(name).encrypt plaintext
69
+ end
70
+
71
+ end
72
+ end
73
+
74
+ module InstanceMethods
75
+ def lock_for name
76
+ @_locks ||= {}
77
+ @_locks[name] ||= Lock.new(name, self, self.class.lock_options[name])
78
+ end
79
+ end
80
+ end
81
+
82
+ if Object.const_defined?("ActiveRecord")
83
+ ActiveRecord::Base.send(:include, Strongbox)
84
+ end
85
+
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__),'../init.rb')
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rjharmon-strongbox
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Spike Ilacqua
8
+ - Randy Harmon
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-12-13 23:00:00 -08:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: thoughtbot-shoulda
18
+ type: :development
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ version:
26
+ description:
27
+ email: r_j_h_box-sf@yahoo.com
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files: []
33
+
34
+ files:
35
+ - LICENSE
36
+ - Rakefile
37
+ - README.textile
38
+ - init.rb
39
+ - lib/strongbox/lock.rb
40
+ - lib/strongbox.rb
41
+ - rails/init.rb
42
+ has_rdoc: true
43
+ homepage: http://stuff-things.net/strongbox
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.3.5
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Secures ActiveRecord fields with public key encryption.
70
+ test_files: []
71
+