attr_encrypted 1.3.3 → 3.0.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.
metadata.gz.sig ADDED
Binary file
data/README.rdoc DELETED
@@ -1,302 +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
-
43
- === Specifying the encrypted attribute name
44
-
45
- 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.
46
-
47
-
48
- ==== The <tt>:attribute</tt> option
49
-
50
- You can simply pass the name of the encrypted attribute as the <tt>:attribute</tt> option:
51
-
52
- class User
53
- attr_encrypted :email, :key => 'a secret key', :attribute => 'email_encrypted'
54
- end
55
-
56
- This would generate an attribute named <tt>email_encrypted</tt>
57
-
58
-
59
- ==== The <tt>:prefix</tt> and <tt>:suffix</tt> options
60
-
61
- 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:
62
-
63
- class User
64
- attr_encrypted :email, :credit_card, :ssn, :key => 'a secret key', :prefix => 'secret_', :suffix => '_crypted'
65
- end
66
-
67
- This would generate the following attributes: <tt>secret_email_crypted</tt>, <tt>secret_credit_card_crypted</tt>, and <tt>secret_ssn_crypted</tt>.
68
-
69
-
70
- === Encryption keys
71
-
72
- Although a <tt>:key</tt> option may not be required (see custom encryptor below), it has a few special features
73
-
74
-
75
- ==== Unique keys for each attribute
76
-
77
- You can specify unique keys for each attribute if you'd like:
78
-
79
- class User
80
- attr_encrypted :email, :key => 'a secret key'
81
- attr_encrypted :ssn, :key => 'a different secret key'
82
- end
83
-
84
-
85
- ==== Symbols representing instance methods as keys
86
-
87
- If your class has an instance method that determines the encryption key to use, simply pass a symbol representing it like so:
88
-
89
- class User
90
- attr_encrypted :email, :key => :encryption_key
91
-
92
- def encryption_key
93
- # does some fancy logic and returns an encryption key
94
- end
95
- end
96
-
97
-
98
- ==== Procs as keys
99
-
100
- You can pass a proc/lambda object as the <tt>:key</tt> option as well:
101
-
102
- class User
103
- attr_encrypted :email, :key => proc { |user| user.key }
104
- end
105
-
106
- This can be used to create asymmetrical encryption by requiring users to provide their own encryption keys.
107
-
108
-
109
- === Conditional encrypting
110
-
111
- 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
112
- attributes when you're in development mode. You can specify conditions like this:
113
-
114
- class User < ActiveRecord::Base
115
- attr_encrypted :email, :key => 'a secret key', :unless => Rails.env.development?
116
- end
117
-
118
- 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.
119
-
120
-
121
- === Custom encryptor
122
-
123
- The <tt>Encryptor</tt> (see http://github.com/shuber/encryptor) class is used by default. You may use your own custom encryptor by specifying
124
- the <tt>:encryptor</tt>, <tt>:encrypt_method</tt>, and <tt>:decrypt_method</tt> options
125
-
126
- Lets suppose you'd like to use this custom encryptor class:
127
-
128
- class SillyEncryptor
129
- def self.silly_encrypt(options)
130
- (options[:value] + options[:secret_key]).reverse
131
- end
132
-
133
- def self.silly_decrypt(options)
134
- options[:value].reverse.gsub(/#{options[:secret_key]}$/, '')
135
- end
136
- end
137
-
138
- Simply set up your class like so:
139
-
140
- class User
141
- attr_encrypted :email, :secret_key => 'a secret key', :encryptor => SillyEncryptor, :encrypt_method => :silly_encrypt, :decrypt_method => :silly_decrypt
142
- end
143
-
144
- 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>.
145
-
146
-
147
- === Custom algorithms
148
-
149
- 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:
150
-
151
- class User
152
- attr_encrypted :email, :key => 'a secret key', :algorithm => 'bf'
153
- end
154
-
155
- 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.
156
-
157
- aes-128-cbc
158
- aes-128-ecb
159
- aes-192-cbc
160
- aes-192-ecb
161
- aes-256-cbc
162
- aes-256-ecb
163
- base64
164
- bf
165
- bf-cbc
166
- bf-cfb
167
- bf-ecb
168
- bf-ofb
169
- cast
170
- cast-cbc
171
- cast5-cbc
172
- cast5-cfb
173
- cast5-ecb
174
- cast5-ofb
175
- des
176
- des-cbc
177
- des-cfb
178
- des-ecb
179
- des-ede
180
- des-ede-cbc
181
- des-ede-cfb
182
- des-ede-ofb
183
- des-ede3
184
- des-ede3-cbc
185
- des-ede3-cfb
186
- des-ede3-ofb
187
- des-ofb
188
- des3
189
- desx
190
- idea
191
- idea-cbc
192
- idea-cfb
193
- idea-ecb
194
- idea-ofb
195
- rc2
196
- rc2-40-cbc
197
- rc2-64-cbc
198
- rc2-cbc
199
- rc2-cfb
200
- rc2-ecb
201
- rc2-ofb
202
- rc4
203
- rc4-40
204
-
205
-
206
- === Default options
207
-
208
- 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:
209
-
210
- class User
211
- attr_encrypted :email, :key => 'a secret key', :prefix => '', :suffix => '_crypted'
212
- attr_encrypted :ssn, :key => 'a different secret key', :prefix => '', :suffix => '_crypted'
213
- attr_encrypted :credit_card, :key => 'another secret key', :prefix => '', :suffix => '_crypted'
214
- end
215
-
216
- You can simply define some default options like so:
217
-
218
- class User
219
- attr_encrypted_options.merge!(:prefix => '', :suffix => '_crypted')
220
- attr_encrypted :email, :key => 'a secret key'
221
- attr_encrypted :ssn, :key => 'a different secret key'
222
- attr_encrypted :credit_card, :key => 'another secret key'
223
- end
224
-
225
- This should help keep your classes clean and DRY.
226
-
227
-
228
- === Encoding
229
-
230
- 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
231
- 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.
232
-
233
- class User
234
- attr_encrypted :email, :key => 'some secret key', :encode => true
235
- end
236
-
237
- 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.
238
-
239
-
240
- === Marshaling
241
-
242
- 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.
243
-
244
- class User
245
- attr_encrypted :credentials, :key => 'some secret key', :marshal => true
246
- end
247
-
248
- 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.
249
-
250
-
251
- === Encrypt/decrypt attribute methods
252
-
253
- If you use the same key to encrypt every record (per attribute) like this:
254
-
255
- class User
256
- attr_encrypted :email, :key => 'a secret key'
257
- end
258
-
259
- 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).
260
-
261
-
262
- === ActiveRecord
263
-
264
- If you're using this gem with <tt>ActiveRecord</tt>, you get a few extra features:
265
-
266
-
267
- ==== Default options
268
-
269
- For your convenience, the <tt>:encode</tt> option is set to true by default since you'll be storing everything in a database.
270
-
271
-
272
- ==== Dynamic find_by_ and scoped_by_ methods
273
-
274
- 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:
275
-
276
- class User < ActiveRecord::Base
277
- attr_encrypted :email, :key => 'a secret key'
278
- attr_encrypted :password, :key => 'some other secret key'
279
- end
280
-
281
- You can now lookup and login users like so:
282
-
283
- User.find_by_email_and_password('test@example.com', 'testing')
284
-
285
- 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.
286
-
287
- NOTE: This only works if all records are encrypted with the same encryption key (per attribute).
288
-
289
-
290
- === DataMapper and Sequel
291
-
292
- 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.
293
-
294
-
295
- == Note on Patches/Pull Requests
296
-
297
- * Fork the project.
298
- * Make your feature addition or bug fix.
299
- * Add tests for it. This is important so I don't break it in a
300
- future version unintentionally.
301
- * 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)
302
- * Send me a pull request. Bonus points for topic branches.