ezcrypto2 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'active_crypto.rb'
@@ -0,0 +1,325 @@
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
+ Options are:
43
+ <tt>key</tt> - to specify an external KeyHolder, which holds the key used for encrypting and decrypting
44
+ <tt>base64</tt> - set to true in order to base64 encode the encrypted attributes. defaults to false
45
+
46
+ class Document < ActiveRecord::Base
47
+ belongs_to :user
48
+ encrypt :title,:body,:key=>:user, :base64 => true
49
+ end
50
+
51
+ =end
52
+ def encrypt(*attributes)
53
+ include ActiveCrypto::Encrypted
54
+ before_save :encrypt_attributes
55
+ after_save :decrypt_attributes
56
+ options=attributes.last.is_a?(Hash) ? attributes.pop : {}
57
+ keyholder
58
+ if options and options[:key]
59
+ module_eval <<-"end;"
60
+ def session_key
61
+ (send :#{options[:key]} ).send :session_key
62
+ end
63
+ @@external_key=true
64
+ end;
65
+ end
66
+
67
+ base64_encode = (options and options[:base64])
68
+ module_eval <<-"end;"
69
+ def self.ezcrypto_base64?
70
+ #{base64_encode.to_s}
71
+ end
72
+ end;
73
+
74
+ self.encrypted_attributes=attributes
75
+ end
76
+
77
+ =begin rdoc
78
+ Creates support in this class for holding a key. Adds the following methods:
79
+
80
+ * enter_password(password,salt="onetwothree")
81
+ * set_session_key(key)
82
+ * session_key
83
+
84
+ Use it as follows:
85
+
86
+ class User < ActiveRecord::Base
87
+ has_many :documents
88
+ keyholder
89
+ end
90
+
91
+ =end
92
+ def keyholder()
93
+ include ActiveCrypto::AssociationKeyHolder
94
+ after_create :save_session_key
95
+ end
96
+
97
+ =begin rdoc
98
+ Clears the session_key array. Generally this is handled automatically as a filter in ActionController. Only use these if you need to
99
+ do something out of the ordinary.
100
+ =end
101
+ def clear_session_keys() #:nodoc:
102
+ @@session_keys.clear
103
+ end
104
+
105
+ =begin rdoc
106
+ Sets the session_keys array. Only use these if you need to
107
+ do something out of the ordinary, as it is handled
108
+ =end
109
+ def session_keys=(keys) #:nodoc:
110
+ @@session_keys=keys
111
+ end
112
+
113
+ def session_keys() #:nodoc:
114
+ @@session_keys
115
+ end
116
+
117
+ end
118
+
119
+ =begin rdoc
120
+ This module handles all standard key management features.
121
+ =end
122
+ module KeyHolder
123
+
124
+ =begin rdoc
125
+ Creates a key for object based on given password and an optional salt.
126
+ =end
127
+ def enter_password(password,salt="onetwothree")
128
+ set_session_key(EzCrypto::Key.with_password(password, salt))
129
+ end
130
+
131
+ =begin rdoc
132
+ Decodes the Base64 encoded key and uses it as it's session key
133
+ =end
134
+ def set_encoded_key(enc)
135
+ set_session_key(EzCrypto::Key.decode(enc))
136
+ end
137
+ =begin rdoc
138
+ Sets a session key for the object. This should be a EzCrypto::Key instance.
139
+ =end
140
+ def set_session_key(key)
141
+ @session_key=key
142
+ self.decrypt_attributes if self.class.include? Encrypted
143
+ end
144
+
145
+ =begin rdoc
146
+ Returns the session_key
147
+ =end
148
+ def session_key
149
+ @session_key
150
+ end
151
+
152
+ end
153
+
154
+ module AssociationKeyHolder
155
+ include ActiveCrypto::KeyHolder
156
+
157
+
158
+ def save_session_key
159
+ ActiveRecord::Base.session_keys[session_key_id]=@session_key if @session_key
160
+ end
161
+ =begin rdoc
162
+ Sets a session key for the object. This should be a EzCrypto::Key instance.
163
+ =end
164
+ def set_session_key(key)
165
+ if self.new_record?
166
+ @session_key=key
167
+ else
168
+ ActiveRecord::Base.session_keys[session_key_id]=key
169
+ end
170
+ decrypt_attributes if self.class.include? Encrypted #if respond_to?(:decrypt_attributes)
171
+
172
+ end
173
+
174
+ =begin rdoc
175
+ Returns the session_key
176
+ =end
177
+ def session_key
178
+ if self.new_record?
179
+ @session_key
180
+ else
181
+ ActiveRecord::Base.session_keys[session_key_id]
182
+ end
183
+ end
184
+
185
+
186
+
187
+ def session_key_id
188
+ "#{self.class.to_s}:#{id}"
189
+ end
190
+
191
+ end
192
+
193
+ module Encrypted #:nodoc:
194
+ def self.append_features(base) #:nodoc:
195
+ super
196
+ base.extend ClassAccessors
197
+ end
198
+
199
+ module ClassAccessors
200
+ def encrypted_attributes
201
+ @encrypted_attributes||=[]
202
+ end
203
+
204
+ def encrypted_attributes=(attrs)
205
+ @encrypted_attributes=attrs
206
+ end
207
+
208
+ end
209
+
210
+ protected
211
+
212
+ def encrypt_attributes
213
+ if !is_encrypted?
214
+ self.class.encrypted_attributes.each do |key|
215
+ value=read_attribute(key)
216
+ write_attribute(key,_encrypt(value)) if value
217
+ end
218
+ @is_encrypted=true
219
+ end
220
+ true
221
+ end
222
+
223
+ def decrypt_attributes
224
+ if is_encrypted?
225
+ self.class.encrypted_attributes.each do |key|
226
+ value=read_attribute(key)
227
+ write_attribute(key,_decrypt(value)) if value
228
+ end
229
+ @is_encrypted=false
230
+ end
231
+ true
232
+ end
233
+
234
+ def after_find
235
+ @is_encrypted=true
236
+ decrypt_attributes unless session_key.nil?
237
+ end
238
+
239
+ private
240
+ def is_encrypted?
241
+ @is_encrypted
242
+ end
243
+
244
+ def _decrypt(data)
245
+ if session_key.nil?
246
+ raise MissingKeyError
247
+ else
248
+ if data
249
+ self.class.ezcrypto_base64? ? session_key.decrypt64(data) : session_key.decrypt(data)
250
+ else
251
+ nil
252
+ end
253
+ end
254
+ end
255
+
256
+ def _encrypt(data)
257
+ if session_key.nil?
258
+ raise MissingKeyError
259
+ else
260
+ if data
261
+ self.class.ezcrypto_base64? ? session_key.encrypt64(data) : session_key.encrypt(data)
262
+ else
263
+ nil
264
+ end
265
+ end
266
+ end
267
+
268
+ end
269
+
270
+
271
+ module ActionController # :nodoc:
272
+ =begin rdoc
273
+ This includes some basic support in the ActionController for handling session keys. It creates two filters one before the action and one after.
274
+ These do the following:
275
+
276
+ If the users session already has a 'session_keys' value it loads it into the ActiveRecord::Base.session_keys class field. If not it
277
+ clears any existing session_keys.
278
+
279
+ Leaving the action it stores any session_keys in the corresponding session variable.
280
+
281
+ These filters are automatically enabled. You do not have to do anything.
282
+
283
+ To manually clear the session keys call clear_session_keys. This should be done for example as part of a session log off action.
284
+ =end
285
+ def self.append_features(base) #:nodoc:
286
+ super
287
+ base.send :prepend_before_filter, :load_session_keys
288
+ base.send :prepend_after_filter, :save_session_keys
289
+ end
290
+
291
+ =begin rdoc
292
+ Clears the session keys. Call this when a user logs of.
293
+ =end
294
+ def clear_session_keys
295
+ ActiveRecord::Base.clear_session_keys
296
+ end
297
+
298
+
299
+ private
300
+ def load_session_keys
301
+ if session['session_keys']
302
+ ActiveRecord::Base.session_keys=session['session_keys']
303
+ else
304
+ ActiveRecord::Base.clear_session_keys
305
+ end
306
+ end
307
+
308
+ def save_session_keys
309
+ if ActiveRecord::Base.session_keys.size>0
310
+ session['session_keys']=ActiveRecord::Base.session_keys
311
+ else
312
+ session['session_keys']=nil
313
+ end
314
+ end
315
+
316
+
317
+ end
318
+
319
+ class MissingKeyError < RuntimeError
320
+ end
321
+ end
322
+ ActiveRecord::Base.send :include, ActiveCrypto
323
+ require 'actionpack'
324
+ require 'action_controller'
325
+ ActionController::Base.send :include, ActiveCrypto::ActionController
data/lib/ezcrypto2.rb ADDED
@@ -0,0 +1,610 @@
1
+ require 'openssl'
2
+ require 'digest/sha2'
3
+ require 'digest/sha1'
4
+ require 'base64'
5
+
6
+ module EzCrypto2 #: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(EzCrypto2::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(EzCrypto2::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 = EzCrypto2::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 = EzCrypto2::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.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<EzCrypto2::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<EzCrypto2::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
+ digest64(key,size)
567
+ end
568
+ =begin rdoc
569
+
570
+ =end
571
+ def self.generate_hexkey(size=40)
572
+ key=OpenSSL::Random.random_bytes(size)
573
+ hexdigest(key,size)
574
+ end
575
+
576
+ =begin rdoc
577
+
578
+ =end
579
+ def self.digest(data,size=16)
580
+ if size==0
581
+ ""
582
+ elsif size<=16
583
+ Digest::SHA1.digest(data)[0..(size-1)]
584
+ else
585
+ Digest::SHA256.digest(data)[0..(size-1)]
586
+ end
587
+ end
588
+
589
+ =begin rdoc
590
+
591
+ =end
592
+ def self.hexdigest(data,size=40)
593
+ if size==0
594
+ ""
595
+ elsif size<=40
596
+ Digest::SHA1.hexdigest(data)[0..(size-1)]
597
+ else
598
+ Digest::SHA256.hexdigest(data)[0..(size-1)]
599
+ end
600
+ end
601
+
602
+ =begin rdoc
603
+
604
+ =end
605
+ def self.digest64(data,size=16)
606
+ Base64.encode64(digest(data,size))
607
+ end
608
+ end
609
+
610
+ end