attr_encrypted 1.3.3 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
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.