attr_encrypted 1.4.0 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc DELETED
@@ -1,344 +0,0 @@
1
- = attr_encrypted {<img src="https://travis-ci.org/attr-encrypted/attr_encrypted.png" />}[https://travis-ci.org/attr-encrypted/attr_encrypted]
2
-
3
- Generates attr_accessors that encrypt and decrypt attributes transparently
4
-
5
- It works with ANY class, however, you get a few extra features when you're using it with <tt>ActiveRecord</tt>, <tt>DataMapper</tt>, or <tt>Sequel</tt>
6
-
7
-
8
- == Installation
9
-
10
- gem install attr_encrypted
11
-
12
-
13
- == Usage
14
-
15
- === Basic
16
-
17
- Encrypting attributes has never been easier:
18
-
19
- class User
20
- attr_accessor :name
21
- attr_encrypted :ssn, :key => 'a secret key'
22
-
23
- def load
24
- # loads the stored data
25
- end
26
-
27
- def save
28
- # saves the :name and :encrypted_ssn attributes somewhere (e.g. filesystem, database, etc)
29
- end
30
- end
31
-
32
- @user = User.new
33
- @user.ssn = '123-45-6789'
34
- @user.encrypted_ssn # returns the encrypted version of :ssn
35
- @user.save
36
-
37
- @user = User.load
38
- @user.ssn # decrypts :encrypted_ssn and returns '123-45-6789'
39
-
40
- The <tt>attr_encrypted</tt> method is also aliased as <tt>attr_encryptor</tt> to conform to Ruby's <tt>attr_</tt> naming conventions. I should have called this project <tt>attr_encryptor</tt> but it was too late when I realized it ='(.
41
-
42
- === Adding required columns via database migration
43
-
44
- By default, <tt>attr_encrypted</tt> uses the <tt>:single_iv_and_salt</tt>
45
- encryption mode for compatibility with previous versions of the gem. This mode
46
- uses a single IV and salt for each encrypted column. Create or modify your model
47
- to add a column with the <tt>encrypted_</tt> prefix (which can be modified, see
48
- below), e.g. <tt>encrypted_ssn</tt> via a migration like the following:
49
-
50
- create_table :users do |t|
51
- t.string :name
52
- t.string :encrypted_ssn
53
- t.timestamps
54
- end
55
-
56
- For enhanced security, you can use the <tt>:per_attribute_iv_and_salt</tt> mode.
57
- This requires additional <tt>_salt</tt> and <tt>_iv</tt> columns with the
58
- <tt>encrypted_</tt> prefix as follows and generates a unique salt and IV per
59
- attribute:
60
-
61
- create_table :users do |t|
62
- t.string :name
63
- t.string :encrypted_ssn
64
- t.string :encrypted_ssn_salt
65
- t.string :encrypted_ssn_iv
66
- t.string :domain
67
- t.timestamps
68
- end
69
-
70
- This mode is enabled by specifying a value of <tt>:per_attribute_iv_and_salt</tt>
71
- via the <tt>:mode</tt> option as follows:
72
-
73
- class User
74
- attr_accessor :name
75
- attr_encrypted :ssn, :key => 'a secret key', :mode => :per_attribute_iv_and_salt
76
- end
77
-
78
- Note that there are alternatives to storing the IV and salt in separate columns:
79
- for example, see here[https://github.com/attr-encrypted/attr_encrypted/issues/118#issuecomment-45806629].
80
- Note that migration from the old encryption scheme to the new is nontrivial. One
81
- approach is described here[http://jjasonclark.com/switching_from_attr_encrypted_to_attr_encryptor],
82
- though these instructions describe the now-defunct <tt>attr_encryptor</tt> gem
83
- whose functionality has been merged into this project.
84
-
85
- === Specifying the encrypted attribute name
86
-
87
- By default, the encrypted attribute name is <tt>encrypted_#{attribute}</tt> (e.g. <tt>attr_encrypted :email</tt> would create an attribute named <tt>encrypted_email</tt>). So, if you're storing the encrypted attribute in the database, you need to make sure the <tt>encrypted_#{attribute}</tt> field exists in your table. You have a couple of options if you want to name your attribute something else.
88
-
89
-
90
- ==== The <tt>:attribute</tt> option
91
-
92
- You can simply pass the name of the encrypted attribute as the <tt>:attribute</tt> option:
93
-
94
- class User
95
- attr_encrypted :email, :key => 'a secret key', :attribute => 'email_encrypted'
96
- end
97
-
98
- This would generate an attribute named <tt>email_encrypted</tt>
99
-
100
-
101
- ==== The <tt>:prefix</tt> and <tt>:suffix</tt> options
102
-
103
- If you're planning on encrypting a few different attributes and you don't like the <tt>encrypted_#{attribute}</tt> naming convention then you can specify your own:
104
-
105
- class User
106
- attr_encrypted :email, :credit_card, :ssn, :key => 'a secret key', :prefix => 'secret_', :suffix => '_crypted'
107
- end
108
-
109
- This would generate the following attributes: <tt>secret_email_crypted</tt>, <tt>secret_credit_card_crypted</tt>, and <tt>secret_ssn_crypted</tt>.
110
-
111
-
112
- === Encryption keys
113
-
114
- Although a <tt>:key</tt> option may not be required (see custom encryptor below), it has a few special features
115
-
116
-
117
- ==== Unique keys for each attribute
118
-
119
- You can specify unique keys for each attribute if you'd like:
120
-
121
- class User
122
- attr_encrypted :email, :key => 'a secret key'
123
- attr_encrypted :ssn, :key => 'a different secret key'
124
- end
125
-
126
-
127
- ==== Symbols representing instance methods as keys
128
-
129
- If your class has an instance method that determines the encryption key to use, simply pass a symbol representing it like so:
130
-
131
- class User
132
- attr_encrypted :email, :key => :encryption_key
133
-
134
- def encryption_key
135
- # does some fancy logic and returns an encryption key
136
- end
137
- end
138
-
139
-
140
- ==== Procs as keys
141
-
142
- You can pass a proc/lambda object as the <tt>:key</tt> option as well:
143
-
144
- class User
145
- attr_encrypted :email, :key => proc { |user| user.key }
146
- end
147
-
148
- This can be used to create asymmetrical encryption by requiring users to provide their own encryption keys.
149
-
150
-
151
- === Conditional encrypting
152
-
153
- There may be times that you want to only encrypt when certain conditions are met. For example maybe you're using rails and you don't want to encrypt
154
- attributes when you're in development mode. You can specify conditions like this:
155
-
156
- class User < ActiveRecord::Base
157
- attr_encrypted :email, :key => 'a secret key', :unless => Rails.env.development?
158
- end
159
-
160
- You can specify both <tt>:if</tt> and <tt>:unless</tt> options. If you pass a symbol representing an instance method then the result of the method will be evaluated. Any objects that respond to <tt>:call</tt> are evaluated as well.
161
-
162
-
163
- === Custom encryptor
164
-
165
- The <tt>Encryptor</tt> (see http://github.com/shuber/encryptor) class is used by default. You may use your own custom encryptor by specifying
166
- the <tt>:encryptor</tt>, <tt>:encrypt_method</tt>, and <tt>:decrypt_method</tt> options
167
-
168
- Lets suppose you'd like to use this custom encryptor class:
169
-
170
- class SillyEncryptor
171
- def self.silly_encrypt(options)
172
- (options[:value] + options[:secret_key]).reverse
173
- end
174
-
175
- def self.silly_decrypt(options)
176
- options[:value].reverse.gsub(/#{options[:secret_key]}$/, '')
177
- end
178
- end
179
-
180
- Simply set up your class like so:
181
-
182
- class User
183
- attr_encrypted :email, :secret_key => 'a secret key', :encryptor => SillyEncryptor, :encrypt_method => :silly_encrypt, :decrypt_method => :silly_decrypt
184
- end
185
-
186
- Any options that you pass to <tt>attr_encrypted</tt> will be passed to the encryptor along with the <tt>:value</tt> option which contains the string to encrypt/decrypt. Notice it uses <tt>:secret_key</tt> instead of <tt>:key</tt>.
187
-
188
-
189
- === Custom algorithms
190
-
191
- The default <tt>Encryptor</tt> uses the standard ruby OpenSSL library. It's default algorithm is <tt>aes-256-cbc</tt>. You can modify this by passing the <tt>:algorithm</tt> option to the <tt>attr_encrypted</tt> call like so:
192
-
193
- class User
194
- attr_encrypted :email, :key => 'a secret key', :algorithm => 'bf'
195
- end
196
-
197
- Run <tt>openssl list-cipher-commands</tt> to view a list of algorithms supported on your platform. See http://github.com/shuber/encryptor for more information.
198
-
199
- aes-128-cbc
200
- aes-128-ecb
201
- aes-192-cbc
202
- aes-192-ecb
203
- aes-256-cbc
204
- aes-256-ecb
205
- base64
206
- bf
207
- bf-cbc
208
- bf-cfb
209
- bf-ecb
210
- bf-ofb
211
- cast
212
- cast-cbc
213
- cast5-cbc
214
- cast5-cfb
215
- cast5-ecb
216
- cast5-ofb
217
- des
218
- des-cbc
219
- des-cfb
220
- des-ecb
221
- des-ede
222
- des-ede-cbc
223
- des-ede-cfb
224
- des-ede-ofb
225
- des-ede3
226
- des-ede3-cbc
227
- des-ede3-cfb
228
- des-ede3-ofb
229
- des-ofb
230
- des3
231
- desx
232
- idea
233
- idea-cbc
234
- idea-cfb
235
- idea-ecb
236
- idea-ofb
237
- rc2
238
- rc2-40-cbc
239
- rc2-64-cbc
240
- rc2-cbc
241
- rc2-cfb
242
- rc2-ecb
243
- rc2-ofb
244
- rc4
245
- rc4-40
246
-
247
-
248
- === Default options
249
-
250
- Let's imagine that you have a few attributes that you want to encrypt with different keys, but you don't like the <tt>encrypted_#{attribute}</tt> naming convention. Instead of having to define your class like this:
251
-
252
- class User
253
- attr_encrypted :email, :key => 'a secret key', :prefix => '', :suffix => '_crypted'
254
- attr_encrypted :ssn, :key => 'a different secret key', :prefix => '', :suffix => '_crypted'
255
- attr_encrypted :credit_card, :key => 'another secret key', :prefix => '', :suffix => '_crypted'
256
- end
257
-
258
- You can simply define some default options like so:
259
-
260
- class User
261
- attr_encrypted_options.merge!(:prefix => '', :suffix => '_crypted')
262
- attr_encrypted :email, :key => 'a secret key'
263
- attr_encrypted :ssn, :key => 'a different secret key'
264
- attr_encrypted :credit_card, :key => 'another secret key'
265
- end
266
-
267
- This should help keep your classes clean and DRY.
268
-
269
-
270
- === Encoding
271
-
272
- You're probably going to be storing your encrypted attributes somehow (e.g. filesystem, database, etc) and may run into some issues trying to store a weird
273
- encrypted string. I've had this problem myself using MySQL. You can simply pass the <tt>:encode</tt> option to automatically encode/decode when encrypting/decrypting.
274
-
275
- class User
276
- attr_encrypted :email, :key => 'some secret key', :encode => true
277
- end
278
-
279
- The default encoding is <tt>m*</tt> (base64). You can change this by setting <tt>:encode => 'some encoding'</tt>. See the <tt>Array#pack</tt> method at http://www.ruby-doc.org/core/classes/Array.html#M002245 for more encoding options.
280
-
281
-
282
- === Marshaling
283
-
284
- You may want to encrypt objects other than strings (e.g. hashes, arrays, etc). If this is the case, simply pass the <tt>:marshal</tt> option to automatically marshal when encrypting/decrypting.
285
-
286
- class User
287
- attr_encrypted :credentials, :key => 'some secret key', :marshal => true
288
- end
289
-
290
- You may also optionally specify <tt>:marshaler</tt>, <tt>:dump_method</tt>, and <tt>:load_method</tt> if you want to use something other than the default <tt>Marshal</tt> object.
291
-
292
-
293
- === Encrypt/decrypt attribute methods
294
-
295
- If you use the same key to encrypt every record (per attribute) like this:
296
-
297
- class User
298
- attr_encrypted :email, :key => 'a secret key'
299
- end
300
-
301
- Then you'll have these two class methods available for each attribute: <tt>User.encrypt_email(email_to_encrypt)</tt> and <tt>User.decrypt_email(email_to_decrypt)</tt>. This can be useful when you're using <tt>ActiveRecord</tt> (see below).
302
-
303
-
304
- === ActiveRecord
305
-
306
- If you're using this gem with <tt>ActiveRecord</tt>, you get a few extra features:
307
-
308
-
309
- ==== Default options
310
-
311
- For your convenience, the <tt>:encode</tt> option is set to true by default since you'll be storing everything in a database.
312
-
313
-
314
- ==== Dynamic find_by_ and scoped_by_ methods
315
-
316
- Let's say you'd like to encrypt your user's email addresses, but you also need a way for them to login. Simply set up your class like so:
317
-
318
- class User < ActiveRecord::Base
319
- attr_encrypted :email, :key => 'a secret key'
320
- attr_encrypted :password, :key => 'some other secret key'
321
- end
322
-
323
- You can now lookup and login users like so:
324
-
325
- User.find_by_email_and_password('test@example.com', 'testing')
326
-
327
- The call to <tt>find_by_email_and_password</tt> is intercepted and modified to <tt>find_by_encrypted_email_and_encrypted_password('ENCRYPTED EMAIL', 'ENCRYPTED PASSWORD')</tt>. The dynamic scope methods like <tt>scoped_by_email_and_password</tt> work the same way.
328
-
329
- NOTE: This only works if all records are encrypted with the same encryption key (per attribute).
330
-
331
-
332
- === DataMapper and Sequel
333
-
334
- Just like the default options for <tt>ActiveRecord</tt>, the <tt>:encode</tt> option is set to true by default since you'll be storing everything in a database.
335
-
336
-
337
- == Note on Patches/Pull Requests
338
-
339
- * Fork the project.
340
- * Make your feature addition or bug fix.
341
- * Add tests for it. This is important so I don't break it in a
342
- future version unintentionally.
343
- * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
344
- * Send me a pull request. Bonus points for topic branches.