mongrel_crypted_download 0.4 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -15,7 +15,7 @@ setup_rdoc ['README', 'LICENSE', 'COPYING', 'lib/**/*.rb', 'doc/**/*.rdoc']
15
15
  desc "Does a full compile, test run"
16
16
  task :default => [:test, :package]
17
17
 
18
- version="0.4"
18
+ version="0.5"
19
19
  name="mongrel_crypted_download"
20
20
 
21
21
  setup_gem(name, version) do |spec|
@@ -0,0 +1,313 @@
1
+ require "ezcrypto.rb"
2
+ module ActiveCrypto # :nodoc:
3
+
4
+ def self.append_features(base) #:nodoc:
5
+ super
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ =begin rdoc
10
+
11
+ Usage is very simple. You will generally only need the two class methods listed here in your ActiveRecord class model.
12
+
13
+ == License
14
+
15
+ ActiveCrypto and EzCrypto are released under the MIT license.
16
+
17
+
18
+ == Support
19
+
20
+ To contact the author, send mail to pelleb@gmail.com
21
+
22
+ Also see my blogs at:
23
+ http://stakeventures.com and
24
+ http://neubia.com
25
+
26
+ This project was based on code used in my project StakeItOut, where you can securely share web services with your partners.
27
+ https://stakeitout.com
28
+
29
+ (C) 2005 Pelle Braendgaard
30
+
31
+ =end
32
+ module ClassMethods
33
+ @@session_keys={}
34
+
35
+ =begin rdoc
36
+ Turn encryption on for this record. List all encrypted attributes
37
+
38
+ class Document < ActiveRecord::Base
39
+ encrypt :title,:body
40
+ end
41
+
42
+ Include optional option :key, to specify an external KeyHolder, which holds the key used for encrypting and decrypting:
43
+
44
+ class Document < ActiveRecord::Base
45
+ belongs_to :user
46
+ encrypt :title,:body,:key=>:user
47
+ end
48
+
49
+ =end
50
+ def encrypt(*attributes)
51
+ include ActiveCrypto::Encrypted
52
+ before_save :encrypt_attributes
53
+ after_save :decrypt_attributes
54
+ options=attributes.last.is_a?(Hash) ? attributes.pop : {}
55
+ keyholder
56
+ if options and options[:key]
57
+ module_eval <<-"end;"
58
+ def session_key
59
+ (send :#{options[:key]} ).send :session_key
60
+ end
61
+ @@external_key=true
62
+ end;
63
+ end
64
+ self.encrypted_attributes=attributes
65
+ end
66
+
67
+ =begin rdoc
68
+ Creates support in this class for holding a key. Adds the following methods:
69
+
70
+ * enter_password(password,salt="onetwothree")
71
+ * set_session_key(key)
72
+ * session_key
73
+
74
+ Use it as follows:
75
+
76
+ class User < ActiveRecord::Base
77
+ has_many :documents
78
+ keyholder
79
+ end
80
+
81
+ =end
82
+ def keyholder()
83
+ include ActiveCrypto::AssociationKeyHolder
84
+ after_create :save_session_key
85
+ end
86
+
87
+ =begin rdoc
88
+ Clears the session_key array. Generally this is handled automatically as a filter in ActionController. Only use these if you need to
89
+ do something out of the ordinary.
90
+ =end
91
+ def clear_session_keys() #:nodoc:
92
+ @@session_keys.clear
93
+ end
94
+
95
+ =begin rdoc
96
+ Sets the session_keys array. Only use these if you need to
97
+ do something out of the ordinary, as it is handled
98
+ =end
99
+ def session_keys=(keys) #:nodoc:
100
+ @@session_keys=keys
101
+ end
102
+
103
+ def session_keys() #:nodoc:
104
+ @@session_keys
105
+ end
106
+
107
+ end
108
+
109
+ =begin rdoc
110
+ This module handles all standard key management features.
111
+ =end
112
+ module KeyHolder
113
+
114
+ =begin rdoc
115
+ Creates a key for object based on given password and an optional salt.
116
+ =end
117
+ def enter_password(password,salt="onetwothree")
118
+ set_session_key(EzCrypto::Key.with_password(password, salt))
119
+ end
120
+
121
+ =begin rdoc
122
+ Decodes the Base64 encoded key and uses it as it's session key
123
+ =end
124
+ def set_encoded_key(enc)
125
+ set_session_key(EzCrypto::Key.decode(enc))
126
+ end
127
+ =begin rdoc
128
+ Sets a session key for the object. This should be a EzCrypto::Key instance.
129
+ =end
130
+ def set_session_key(key)
131
+ @session_key=key
132
+ self.decrypt_attributes if self.class.include? Encrypted
133
+ end
134
+
135
+ =begin rdoc
136
+ Returns the session_key
137
+ =end
138
+ def session_key
139
+ @session_key
140
+ end
141
+
142
+ end
143
+
144
+ module AssociationKeyHolder
145
+ include ActiveCrypto::KeyHolder
146
+
147
+
148
+ def save_session_key
149
+ ActiveRecord::Base.session_keys[session_key_id]=@session_key if @session_key
150
+ end
151
+ =begin rdoc
152
+ Sets a session key for the object. This should be a EzCrypto::Key instance.
153
+ =end
154
+ def set_session_key(key)
155
+ if self.new_record?
156
+ @session_key=key
157
+ else
158
+ ActiveRecord::Base.session_keys[session_key_id]=key
159
+ end
160
+ decrypt_attributes if self.class.include? Encrypted #if respond_to?(:decrypt_attributes)
161
+
162
+ end
163
+
164
+ =begin rdoc
165
+ Returns the session_key
166
+ =end
167
+ def session_key
168
+ if self.new_record?
169
+ @session_key
170
+ else
171
+ ActiveRecord::Base.session_keys[session_key_id]
172
+ end
173
+ end
174
+
175
+
176
+
177
+ def session_key_id
178
+ "#{self.class.to_s}:#{id}"
179
+ end
180
+
181
+ end
182
+
183
+ module Encrypted #:nodoc:
184
+ def self.append_features(base) #:nodoc:
185
+ super
186
+ base.extend ClassAccessors
187
+ end
188
+
189
+ module ClassAccessors
190
+ def encrypted_attributes
191
+ @encrypted_attributes||=[]
192
+ end
193
+
194
+ def encrypted_attributes=(attrs)
195
+ @encrypted_attributes=attrs
196
+ end
197
+
198
+ end
199
+
200
+ protected
201
+
202
+ def encrypt_attributes
203
+ if !is_encrypted?
204
+ self.class.encrypted_attributes.each do |key|
205
+ value=read_attribute(key)
206
+ write_attribute(key,_encrypt(value)) if value
207
+ end
208
+ @is_encrypted=true
209
+ end
210
+ true
211
+ end
212
+
213
+ def decrypt_attributes
214
+ if is_encrypted?
215
+ self.class.encrypted_attributes.each do |key|
216
+ value=read_attribute(key)
217
+ write_attribute(key,_decrypt(value)) if value
218
+ end
219
+ @is_encrypted=false
220
+ end
221
+ true
222
+ end
223
+
224
+ def after_find
225
+ @is_encrypted=true
226
+ decrypt_attributes unless session_key.nil?
227
+ end
228
+
229
+ private
230
+ def is_encrypted?
231
+ @is_encrypted
232
+ end
233
+
234
+ def _decrypt(data)
235
+ if session_key.nil?
236
+ raise MissingKeyError
237
+ else
238
+ if data
239
+ session_key.decrypt(data)
240
+ else
241
+ nil
242
+ end
243
+ end
244
+ end
245
+
246
+ def _encrypt(data)
247
+ if session_key.nil?
248
+ raise MissingKeyError
249
+ else
250
+ if data
251
+ session_key.encrypt(data)
252
+ else
253
+ nil
254
+ end
255
+ end
256
+ end
257
+
258
+ end
259
+
260
+
261
+ module ActionController # :nodoc:
262
+ =begin rdoc
263
+ This includes some basic support in the ActionController for handling session keys. It creates two filters one before the action and one after.
264
+ These do the following:
265
+
266
+ If the users session already has a 'session_keys' value it loads it into the ActiveRecord::Base.session_keys class field. If not it
267
+ clears any existing session_keys.
268
+
269
+ Leaving the action it stores any session_keys in the corresponding session variable.
270
+
271
+ These filters are automatically enabled. You do not have to do anything.
272
+
273
+ To manually clear the session keys call clear_session_keys. This should be done for example as part of a session log off action.
274
+ =end
275
+ def self.append_features(base) #:nodoc:
276
+ super
277
+ base.send :prepend_before_filter, :load_session_keys
278
+ base.send :prepend_after_filter, :save_session_keys
279
+ end
280
+
281
+ =begin rdoc
282
+ Clears the session keys. Call this when a user logs of.
283
+ =end
284
+ def clear_session_keys
285
+ ActiveRecord::Base.clear_session_keys
286
+ end
287
+
288
+
289
+ private
290
+ def load_session_keys
291
+ if session['session_keys']
292
+ ActiveRecord::Base.session_keys=session['session_keys']
293
+ else
294
+ ActiveRecord::Base.clear_session_keys
295
+ end
296
+ end
297
+
298
+ def save_session_keys
299
+ if ActiveRecord::Base.session_keys.size>0
300
+ session['session_keys']=ActiveRecord::Base.session_keys
301
+ else
302
+ session['session_keys']=nil
303
+ end
304
+ end
305
+
306
+
307
+ end
308
+
309
+ class MissingKeyError < RuntimeError
310
+ end
311
+ end
312
+ #ActiveRecord::Base.send :include, ActiveCrypto
313
+ #ActionController::Base.send :include, ActiveCrypto::ActionController
data/lib/ezcrypto.rb ADDED
@@ -0,0 +1,592 @@
1
+ require 'openssl'
2
+ require 'digest/sha2'
3
+ require 'digest/sha1'
4
+ require 'base64'
5
+
6
+ module EzCrypto #:nodoc:
7
+
8
+
9
+ =begin rdoc
10
+ The Key is the only class you need to understand for simple use.
11
+
12
+ === Algorithms
13
+
14
+ The crypto algorithms default to aes-128-cbc however on any of the class methods you can change it to one of the standard openssl cipher names using the
15
+ optional <tt>:algorithm=>alg name</tt> parameter.
16
+
17
+ Eg.
18
+ Key.new @raw, :algorithm=>"des"
19
+ Key.generate :algorithm=>"blowfish"
20
+ Key.with_password @pwd,@salt,:algorithm=>"aes256"
21
+
22
+
23
+ == License
24
+
25
+ ActiveCrypto and EzCrypto are released under the MIT license.
26
+
27
+
28
+ == Support
29
+
30
+ To contact the author, send mail to pelleb@gmail.com
31
+
32
+ Also see my blogs at:
33
+ http://stakeventures.com and
34
+ http://neubia.com
35
+
36
+ This project was based on code used in my project StakeItOut, where you can securely share web services with your partners.
37
+ https://stakeitout.com
38
+
39
+ (C) 2005 Pelle Braendgaard
40
+
41
+ =end
42
+
43
+ class Key
44
+
45
+ attr_reader :raw, :algorithm
46
+
47
+ @@block_size = 512
48
+
49
+ =begin rdoc
50
+ Set the block-size for IO-operations (default: 512 bytes)
51
+ =end
52
+ def self.block_size=(size)
53
+ @@block_size = size
54
+ end
55
+
56
+ =begin rdoc
57
+ Return the block-size for IO-operations.
58
+ =end
59
+ def self.block_size
60
+ @@block_size
61
+ end
62
+
63
+
64
+ =begin rdoc
65
+ Initialize the key with raw unencoded binary key data. This needs to be at least
66
+ 16 bytes long for the default aes-128 algorithm.
67
+ =end
68
+ def initialize(raw,options = {})
69
+ @raw=raw
70
+ @algorithm=options[:algorithm]||"aes-128-cbc"
71
+ end
72
+
73
+ =begin rdoc
74
+ Generate random key.
75
+ =end
76
+ def self.generate(options = {})
77
+ Key.new(EzCrypto::Digester.generate_key(calculate_key_size(options[:algorithm])),options)
78
+ end
79
+
80
+ =begin rdoc
81
+ Create key generated from the given password and salt
82
+ =end
83
+ def self.with_password(password,salt,options = {})
84
+ Key.new(EzCrypto::Digester.get_key(password,salt,calculate_key_size(options[:algorithm])),options)
85
+ end
86
+
87
+ =begin rdoc
88
+ Initialize the key with Base64 encoded key data.
89
+ =end
90
+ def self.decode(encoded,options = {})
91
+ Key.new(Base64.decode64(encoded),options)
92
+ end
93
+
94
+ =begin rdoc
95
+ Encrypts the data with the given password and a salt. Short hand for:
96
+
97
+ key=Key.with_password(password,salt,options)
98
+ key.encrypt(data)
99
+
100
+ =end
101
+ def self.encrypt_with_password(password,salt,data,options = {})
102
+ key=Key.with_password(password,salt,options)
103
+ key.encrypt(data)
104
+ end
105
+
106
+ =begin rdoc
107
+ Decrypts the data with the given password and a salt. Short hand for:
108
+
109
+ key=Key.with_password(password,salt,options)
110
+ key.decrypt(data)
111
+
112
+
113
+ =end
114
+ def self.decrypt_with_password(password,salt,data,options = {})
115
+ key=Key.with_password(password,salt,options)
116
+ key.decrypt(data)
117
+ end
118
+
119
+ =begin rdoc
120
+ Given an algorithm this calculates the keysize. This is used by both
121
+ the generate and with_password methods. This is not yet 100% complete.
122
+ =end
123
+ def self.calculate_key_size(algorithm)
124
+ if !algorithm.nil?
125
+ algorithm=~/^([[:alnum:]]+)(-(\d+))?/
126
+ if $3
127
+ size=($3.to_i)/8
128
+ else
129
+ case $1
130
+ when "bf"
131
+ size = 16
132
+ when "blowfish"
133
+ size = 16
134
+ when "des"
135
+ size = 8
136
+ when "des3"
137
+ size = 24
138
+ when "aes128"
139
+ size = 16
140
+ when "aes192"
141
+ size = 24
142
+ when "aes256"
143
+ size = 32
144
+ when "rc2"
145
+ size = 16
146
+ when "rc4"
147
+ size = 16
148
+ else
149
+ size = 16
150
+ end
151
+ end
152
+ end
153
+ if size.nil?
154
+ size = 16
155
+ end
156
+
157
+ size
158
+ end
159
+
160
+ =begin rdoc
161
+ returns the Base64 encoded key.
162
+ =end
163
+ def encode
164
+ Base64.encode64(@raw).chop
165
+ end
166
+
167
+ =begin rdoc
168
+ returns the Base64 encoded key. Synonym for encode.
169
+ =end
170
+ def to_s
171
+ encode
172
+ end
173
+
174
+ =begin rdoc
175
+ Encrypts the data and returns it in encrypted binary form.
176
+ =end
177
+ def encrypt(data)
178
+ if data==nil || data==""
179
+ nil
180
+ else
181
+ encrypter("")
182
+ @cipher.encrypt(data)
183
+ end
184
+ end
185
+
186
+ =begin rdoc
187
+ Encrypts the data and returns it in encrypted Base64 encoded form.
188
+ =end
189
+ def encrypt64(data)
190
+ Base64.encode64(encrypt(data))
191
+ end
192
+
193
+ =begin rdoc
194
+ Decrypts the data passed to it in binary format.
195
+ =end
196
+ def decrypt(data)
197
+ if data==nil || data==""
198
+ nil
199
+ else
200
+ decrypter("")
201
+ @cipher.gulp(data)
202
+ end
203
+ # rescue
204
+ # puts @algorithm
205
+ # puts self.encode
206
+ # puts data.size
207
+ # throw $!
208
+ end
209
+
210
+ =begin rdoc
211
+ Decrypts a Base64 formatted string
212
+ =end
213
+ def decrypt64(data)
214
+ decrypt(Base64.decode64(data))
215
+ end
216
+
217
+ =begin rdoc
218
+ Allows keys to be marshalled
219
+ =end
220
+ def marshal_dump
221
+ "#{self.algorithm}$$$#{self.encode}"
222
+ end
223
+
224
+ =begin rdoc
225
+ Allows keys to be unmarshalled
226
+ =end
227
+ def marshal_load(s)
228
+ a, r = s.split '$$$'
229
+ @algorithm = a
230
+ @raw = Base64.decode64(r)
231
+ end
232
+
233
+ =begin rdoc
234
+ Create a file with minimal permissions, and yield
235
+ it to a block. By default only the owner may read it.
236
+ =end
237
+ def safe_create(file, mod=0400, mask=0066)
238
+ begin
239
+ old_umask = File.umask
240
+ File.umask(mask)
241
+ File.open(file, File::CREAT | File::EXCL | File::WRONLY) do |f|
242
+ yield(f) if block_given?
243
+ end
244
+ ensure
245
+ File.umask(old_umask)
246
+ end
247
+ File.chmod(mod, file) if File.exists?(file)
248
+ File.size(file)
249
+ end
250
+
251
+
252
+ =begin rdoc
253
+ Overwrite a file with zero values before removing it's filesystem inode.
254
+ This is not very safe :-)
255
+ =end
256
+ def safe_delete(file)
257
+ begin
258
+ to_clear = File.size(file)
259
+ zeroes = Array.new(Key.block_size, "\0").join
260
+ File.chmod(0600, file)
261
+ File.open(file, File::WRONLY) do |f|
262
+ f.rewind
263
+ while to_clear > 0
264
+ f.write(zeroes)
265
+ to_clear -= Key.block_size
266
+ end
267
+ f.flush
268
+ end
269
+ ensure
270
+ File.delete(file) if File.exists?(file)
271
+ end
272
+ return !File.exists?(file)
273
+ end
274
+
275
+
276
+ =begin rdoc
277
+ Open a file readonly and yield it to a block.
278
+ =end
279
+ def safe_read(file)
280
+ File.open(file, File::RDONLY) do |i|
281
+ yield(i) if block_given?
282
+ end
283
+ end
284
+
285
+ private :safe_create, :safe_read, :safe_delete
286
+
287
+ =begin rdoc
288
+ Load a key from a yaml_file generated via Key#store.
289
+ =end
290
+ def self.load(filename)
291
+ require 'yaml'
292
+ hash = YAML::load_file(filename)
293
+ req = proc { |k| hash[k] or raise "Missing element #{k} in #{filename}" }
294
+ key = self.new Base64.decode64(req.call(:key)) , :algorithm => req.call(:algorithm)
295
+ return key
296
+ end
297
+
298
+
299
+ =begin rdoc
300
+ Save the key data into a file, try to do this in a secure manner.
301
+ NOTE: YAML::store & friends are not used to encance control over
302
+ the generated file format.
303
+ =end
304
+ def store(filename)
305
+ safe_create(filename) do |f|
306
+ selfenc = self.encode
307
+ f.puts "---"
308
+ f.puts ":EZCRYPTO KEY FILE: KEEP THIS SECURE !"
309
+ f.puts ":created: #{Time.now}"
310
+ f.puts ":algorithm: #{@algorithm}"
311
+ f.puts ":key: #{selfenc}"
312
+ end
313
+ end
314
+
315
+
316
+ =begin rdoc
317
+ Get a Encrypter object. You have to call #final on it by yourself!
318
+ =end
319
+ def encrypter(target='')
320
+ @cipher = EzCrypto::Encrypter.new(self,target,@algorithm)
321
+ end
322
+
323
+
324
+ =begin rdoc
325
+ Get a Decrypter object. You have to call #final on it by yourself!
326
+ =end
327
+ def decrypter(target='')
328
+ @cipher = EzCrypto::Decrypter.new(self,target,@algorithm)
329
+ end
330
+
331
+ =begin rdoc
332
+ Create a Decrypter object and yield it to a block.
333
+ You must *not* call #final by yourself, the method
334
+ does this.
335
+ =end
336
+ def on_decrypter(target='', &block)
337
+ decrypter(target)
338
+ on_cipher(&block)
339
+ end
340
+
341
+ =begin rdoc
342
+ Create an Encrypter object and yield it to a block.
343
+ You must *not* call #final by yourself, the method
344
+ does this.
345
+ =end
346
+ def on_encrypter(target='', &block)
347
+ encrypter(target)
348
+ on_cipher(&block)
349
+ end
350
+
351
+
352
+ =begin rdoc
353
+ Helper method, yields the current cipher to a block.
354
+ =end
355
+ def on_cipher(&block)
356
+ begin
357
+ block.call @cipher
358
+ ensure
359
+ @cipher.final
360
+ end
361
+ end
362
+
363
+ private :on_cipher
364
+
365
+
366
+ =begin rdoc
367
+ Encrypt a file 'inplace' and add a suffix
368
+ see #cipher_file.
369
+ IMPORTANT: The inputfile will be deleted by default.
370
+ =end
371
+ def encrypt_file(src, tgt=nil, options = {} )
372
+ options = { :suffix => '.ez', :autoclean => 'true' }.update(options)
373
+ tgt = "#{src}#{options[:suffix]}" unless tgt
374
+ cipher_file :on_encrypter, src, tgt, options[:autoclean]
375
+ end
376
+
377
+
378
+ =begin rdoc
379
+ Decrypt a file 'inplace' and remove a suffix
380
+ see #cipher_file
381
+ IMPORTANT: The inputfile will be deleted by default.
382
+ =end
383
+ def decrypt_file(src, tgt=nil, options = {} )
384
+ options = { :suffix => '.ez', :autoclean => 'true' }.update(options)
385
+ unless tgt
386
+ tgt = src
387
+ tgt = tgt.gsub(/#{options[:suffix]}$/, '')
388
+ end
389
+ cipher_file :on_decrypter, src, tgt, options[:autoclean]
390
+ end
391
+
392
+
393
+ =begin rdoc
394
+ uses either #on_decrypter or #on_encrypter to transform a given sourcefile
395
+ to a targetfile. the sourcefile is deleted after sucessful transformation
396
+ the delete_source is 'true'.
397
+ =end
398
+ def cipher_file(method, sourcefile, targetfile, delete_source)
399
+ raise(ArgumentError, "source == target #{sourcefile}") if sourcefile == targetfile
400
+ safe_create(targetfile,0600) do |o|
401
+ self.send(method, o) do |c|
402
+ safe_read(sourcefile) do |i|
403
+ loop do
404
+ buffer = i.read(Key.block_size) or break
405
+ c << buffer
406
+ end
407
+ end
408
+ end
409
+ end
410
+ safe_delete(sourcefile) if delete_source && File.exists?(targetfile)
411
+ return targetfile
412
+ end
413
+
414
+ private :cipher_file
415
+
416
+ end
417
+
418
+ =begin rdoc
419
+ Abstract Wrapper around OpenSSL's Cipher object. Extended by Encrypter and Decrypter.
420
+
421
+ You probably should be using the Key class instead.
422
+
423
+ Warning! The interface may change.
424
+
425
+ =end
426
+ class CipherWrapper #:nodoc:
427
+
428
+ =begin rdoc
429
+
430
+ =end
431
+ def initialize(key,target,mode,algorithm)
432
+ @cipher = OpenSSL::Cipher::Cipher.new(algorithm)
433
+ if mode
434
+ @cipher.encrypt
435
+ else
436
+ @cipher.decrypt
437
+ end
438
+ @cipher.key=key.raw
439
+ @cipher.padding=1
440
+ @target=target
441
+ @finished=false
442
+ end
443
+
444
+
445
+ def to_target(data)
446
+ return data
447
+ end
448
+
449
+ =begin rdoc
450
+ Process the givend data with the cipher.
451
+ =end
452
+ def update(data)
453
+ reset if @finished
454
+ @target<< to_target(@cipher.update(data))
455
+ end
456
+
457
+ =begin rdoc
458
+
459
+ =end
460
+ def <<(data)
461
+ update(data)
462
+ end
463
+
464
+ =begin rdoc
465
+ Finishes up any last bits of data in the cipher and returns the final result.
466
+ =end
467
+ def final
468
+ @target<< to_target(@cipher.final)
469
+ @finished=true
470
+ @target
471
+ end
472
+
473
+ =begin rdoc
474
+ Processes the entire data string using update and performs a final on it returning the data.
475
+ =end
476
+ def gulp(data)
477
+ update(data)
478
+ final
479
+ # rescue
480
+ # breakpoint
481
+ end
482
+
483
+ =begin rdoc
484
+
485
+ =end
486
+ def reset(target="")
487
+ @target=target
488
+ @finished=false
489
+ end
490
+ end
491
+
492
+ =begin rdoc
493
+ Wrapper around OpenSSL Cipher for Encryption use.
494
+
495
+ You probably should be using Key instead.
496
+
497
+ Warning! The interface may change.
498
+
499
+ =end
500
+ class Encrypter<EzCrypto::CipherWrapper #:nodoc:
501
+
502
+ =begin rdoc
503
+
504
+ =end
505
+ def initialize(key,target="",algorithm="aes-128-cbc")
506
+ super(key,target,true,algorithm)
507
+ end
508
+
509
+ =begin rdoc
510
+
511
+ =end
512
+ def encrypt(data)
513
+ gulp(data)
514
+ end
515
+ end
516
+
517
+ =begin rdoc
518
+ Wrapper around OpenSSL Cipher for Decryption use.
519
+
520
+ You probably should be using Key instead.
521
+
522
+ Warning! The interface may change.
523
+ =end
524
+ class Decrypter<EzCrypto::CipherWrapper #:nodoc:
525
+ =begin rdoc
526
+
527
+ =end
528
+ def initialize(key,target="",algorithm="aes-128-cbc")
529
+ super(key,target,false,algorithm)
530
+ end
531
+
532
+ =begin rdoc
533
+
534
+ =end
535
+ def decrypt(data)
536
+ gulp(data)
537
+ end
538
+ end
539
+
540
+ =begin rdoc
541
+
542
+ =end
543
+ class Digester
544
+ =begin rdoc
545
+ Various handy Digest methods.
546
+
547
+ Warning! The interface may change.
548
+ =end
549
+ def self.get_key(password,salt,size)
550
+ digest(salt+password,size)
551
+ end
552
+
553
+ =begin rdoc
554
+
555
+ =end
556
+ def self.generate_key(size=16)
557
+ key=OpenSSL::Random.random_bytes(size)
558
+ digest(key,size)
559
+ end
560
+
561
+ =begin rdoc
562
+
563
+ =end
564
+ def self.generate_key64(size=32)
565
+ key=OpenSSL::Random.random_bytes(size)
566
+ digest(key,size)
567
+ end
568
+
569
+ =begin rdoc
570
+
571
+ =end
572
+ def self.digest(data,size=16)
573
+ if size==0
574
+ ""
575
+ elsif size<=16
576
+ Digest::SHA1.digest(data)[0..(size-1)]
577
+ else
578
+ Digest::SHA256.digest(data)[0..(size-1)]
579
+ end
580
+ end
581
+
582
+ =begin rdoc
583
+
584
+ =end
585
+ def self.digest64(data)
586
+ Base64.encode64(digest(data))
587
+ end
588
+ end
589
+
590
+ end
591
+
592
+