encrypted_strings 0.2.1 → 0.3.0

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.
@@ -1,68 +1,66 @@
1
1
  require 'digest/sha1'
2
2
 
3
- module PluginAWeek #:nodoc:
4
- module EncryptedStrings
5
- # Encrypts a string using a Secure Hash Algorithm (SHA), specifically SHA-1.
6
- #
7
- # == Encrypting
8
- #
9
- # To encrypt a string using an SHA cipher, the salt used to seed the
10
- # algorithm must be specified. You can define the default for this value
11
- # like so:
12
- #
13
- # PluginAWeek::EncryptedStrings::ShaCipher.default_salt = 'secret'
14
- #
15
- # If these configuration options are not passed in to #encrypt, then the
16
- # default values will be used. You can override the default values like so:
17
- #
18
- # password = 'shhhh'
19
- # password.encrypt(:sha, :salt => 'secret') # => "ae645b35bb5dfea6c9133ac872e6adfa92a3c2bd"
20
- #
21
- # == Decrypting
22
- #
23
- # SHA-encrypted strings cannot be decrypted. The only way to determine
24
- # whether an unencrypted value is equal to an SHA-encrypted string is to
25
- # encrypt the value with the same salt. For example,
3
+ module EncryptedStrings
4
+ # Encrypts a string using a Secure Hash Algorithm (SHA), specifically SHA-1.
5
+ #
6
+ # == Encrypting
7
+ #
8
+ # To encrypt a string using an SHA cipher, the salt used to seed the
9
+ # algorithm must be specified. You can define the default for this value
10
+ # like so:
11
+ #
12
+ # EncryptedStrings::ShaCipher.default_salt = 'secret'
13
+ #
14
+ # If these configuration options are not passed in to #encrypt, then the
15
+ # default values will be used. You can override the default values like so:
16
+ #
17
+ # password = 'shhhh'
18
+ # password.encrypt(:sha, :salt => 'secret') # => "ae645b35bb5dfea6c9133ac872e6adfa92a3c2bd"
19
+ #
20
+ # == Decrypting
21
+ #
22
+ # SHA-encrypted strings cannot be decrypted. The only way to determine
23
+ # whether an unencrypted value is equal to an SHA-encrypted string is to
24
+ # encrypt the value with the same salt. For example,
25
+ #
26
+ # password = 'shhhh'.encrypt(:sha, :salt => 'secret') # => "3b22cbe4acde873c3efc82681096f3ae69aff828"
27
+ # input = 'shhhh'.encrypt(:sha, :salt => 'secret') # => "3b22cbe4acde873c3efc82681096f3ae69aff828"
28
+ # password == input # => true
29
+ class ShaCipher < Cipher
30
+ class << self
31
+ # The default salt value to use during encryption
32
+ attr_accessor :default_salt
33
+ end
34
+
35
+ # Set defaults
36
+ @default_salt = 'salt'
37
+
38
+ # The salt value to use for encryption
39
+ attr_accessor :salt
40
+
41
+ # Creates a new cipher that uses an SHA encryption strategy.
26
42
  #
27
- # password = 'shhhh'.encrypt(:sha, :salt => 'secret') # => "3b22cbe4acde873c3efc82681096f3ae69aff828"
28
- # input = 'shhhh'.encrypt(:sha, :salt => 'secret') # => "3b22cbe4acde873c3efc82681096f3ae69aff828"
29
- # password == input # => true
30
- class ShaCipher < Cipher
31
- class << self
32
- # The default salt value to use during encryption
33
- attr_accessor :default_salt
34
- end
35
-
36
- # Set defaults
37
- @default_salt = 'salt'
43
+ # Configuration options:
44
+ # * +salt+ - Random bytes used as one of the inputs for generating the encrypted string
45
+ def initialize(options = {})
46
+ invalid_options = options.keys - [:salt]
47
+ raise ArgumentError, "Unknown key(s): #{invalid_options.join(", ")}" unless invalid_options.empty?
38
48
 
39
- # The salt value to use for encryption
40
- attr_accessor :salt
49
+ options = {:salt => ShaCipher.default_salt}.merge(options)
41
50
 
42
- # Creates a new cipher that uses an SHA encryption strategy.
43
- #
44
- # Configuration options:
45
- # * +salt+ - Random bytes used as one of the inputs for generating the encrypted string
46
- def initialize(options = {})
47
- invalid_options = options.keys - [:salt]
48
- raise ArgumentError, "Unknown key(s): #{invalid_options.join(", ")}" unless invalid_options.empty?
49
-
50
- options = {:salt => ShaCipher.default_salt}.merge(options)
51
-
52
- self.salt = options[:salt].to_s
53
-
54
- super()
55
- end
51
+ self.salt = options[:salt].to_s
56
52
 
57
- # Decryption is not supported
58
- def can_decrypt?
59
- false
60
- end
61
-
62
- # Returns the encrypted value of the data
63
- def encrypt(data)
64
- Digest::SHA1.hexdigest(data + salt)
65
- end
53
+ super()
54
+ end
55
+
56
+ # Decryption is not supported
57
+ def can_decrypt?
58
+ false
59
+ end
60
+
61
+ # Returns the encrypted value of the data
62
+ def encrypt(data)
63
+ Digest::SHA1.hexdigest(data + salt)
66
64
  end
67
65
  end
68
66
  end
@@ -1,102 +1,100 @@
1
- module PluginAWeek #:nodoc:
2
- module EncryptedStrings
3
- # Indicates no password was specified for the symmetric cipher
4
- class NoPasswordError < StandardError
1
+ module EncryptedStrings
2
+ # Indicates no password was specified for the symmetric cipher
3
+ class NoPasswordError < StandardError
4
+ end
5
+
6
+ # Symmetric encryption uses a specific algorithm and password to encrypt
7
+ # the string. As long as the algorithm and password are known, the string
8
+ # can be decrypted.
9
+ #
10
+ # Source: http://support.microsoft.com/kb/246071
11
+ #
12
+ # == Encrypting
13
+ #
14
+ # To encrypt a string using a symmetric cipher, the algorithm and password
15
+ # must be specified. You can define the defaults for these values like so:
16
+ #
17
+ # EncryptedStrings::SymmetricCipher.default_algorithm = 'des-ecb'
18
+ # EncryptedStrings::SymmetricCipher.default_password = 'secret'
19
+ #
20
+ # If these configuration options are not passed in to #encrypt, then the
21
+ # default values will be used. You can override the default values like so:
22
+ #
23
+ # password = 'shhhh'
24
+ # password.encrypt(:symmetric, :algorithm => 'des-ecb', :password => 'secret') # => "S/sEkViX3v4=\n"
25
+ #
26
+ # An exception will be raised if no password is specified.
27
+ #
28
+ # == Decrypting
29
+ #
30
+ # To decrypt a string using an symmetric cipher, the algorithm and password
31
+ # must be specified. Defaults for these values can be defined as show above.
32
+ #
33
+ # If these configuration options are not passed in to #decrypt, then the
34
+ # default values will be used. You can override the default values like so:
35
+ #
36
+ # password = "S/sEkViX3v4=\n"
37
+ # password.decrypt(:symmetric, :algorithm => 'des-ecb', :password => 'secret') # => "shhhh"
38
+ #
39
+ # An exception will be raised if no password is specified.
40
+ class SymmetricCipher < Cipher
41
+ class << self
42
+ # The default algorithm to use for encryption. Default is DES-EDE3-CBC.
43
+ attr_accessor :default_algorithm
44
+
45
+ # The default password to use for generating the key and initialization
46
+ # vector. Default is nil.
47
+ attr_accessor :default_password
5
48
  end
6
49
 
7
- # Symmetric encryption uses a specific algorithm and password to encrypt
8
- # the string. As long as the algorithm and password are known, the string
9
- # can be decrypted.
10
- #
11
- # Source: http://support.microsoft.com/kb/246071
12
- #
13
- # == Encrypting
14
- #
15
- # To encrypt a string using a symmetric cipher, the algorithm and password
16
- # must be specified. You can define the defaults for these values like so:
17
- #
18
- # PluginAWeek::EncryptedStrings::SymmetricCipher.default_algorithm = 'des-ecb'
19
- # PluginAWeek::EncryptedStrings::SymmetricCipher.default_password = 'secret'
20
- #
21
- # If these configuration options are not passed in to #encrypt, then the
22
- # default values will be used. You can override the default values like so:
23
- #
24
- # password = 'shhhh'
25
- # password.encrypt(:symmetric, :algorithm => 'des-ecb', :password => 'secret') # => "S/sEkViX3v4=\n"
26
- #
27
- # An exception will be raised if no password is specified.
28
- #
29
- # == Decrypting
30
- #
31
- # To decrypt a string using an symmetric cipher, the algorithm and password
32
- # must be specified. Defaults for these values can be defined as show above.
33
- #
34
- # If these configuration options are not passed in to #decrypt, then the
35
- # default values will be used. You can override the default values like so:
36
- #
37
- # password = "S/sEkViX3v4=\n"
38
- # password.decrypt(:symmetric, :algorithm => 'des-ecb', :password => 'secret') # => "shhhh"
50
+ # Set default values
51
+ @default_algorithm = 'DES-EDE3-CBC'
52
+
53
+ # The algorithm to use for encryption/decryption
54
+ attr_accessor :algorithm
55
+
56
+ # The password that generates the key/initialization vector for the
57
+ # algorithm
58
+ attr_accessor :password
59
+
60
+ # Creates a new cipher that uses a symmetric encryption strategy.
39
61
  #
40
- # An exception will be raised if no password is specified.
41
- class SymmetricCipher < Cipher
42
- class << self
43
- # The default algorithm to use for encryption. Default is DES-EDE3-CBC.
44
- attr_accessor :default_algorithm
45
-
46
- # The default password to use for generating the key and initialization
47
- # vector. Default is nil.
48
- attr_accessor :default_password
49
- end
50
-
51
- # Set default values
52
- @default_algorithm = 'DES-EDE3-CBC'
53
-
54
- # The algorithm to use for encryption/decryption
55
- attr_accessor :algorithm
62
+ # Configuration options:
63
+ # * +algorithm+ - The algorithm to use for generating the encrypted string
64
+ # * +password+ - The secret value to use for generating the key/initialization vector for the algorithm
65
+ def initialize(options = {})
66
+ invalid_options = options.keys - [:algorithm, :password]
67
+ raise ArgumentError, "Unknown key(s): #{invalid_options.join(", ")}" unless invalid_options.empty?
56
68
 
57
- # The password that generates the key/initialization vector for the
58
- # algorithm
59
- attr_accessor :password
69
+ options = {
70
+ :algorithm => SymmetricCipher.default_algorithm,
71
+ :password => SymmetricCipher.default_password
72
+ }.merge(options)
60
73
 
61
- # Creates a new cipher that uses a symmetric encryption strategy.
62
- #
63
- # Configuration options:
64
- # * +algorithm+ - The algorithm to use for generating the encrypted string
65
- # * +password+ - The secret value to use for generating the key/initialization vector for the algorithm
66
- def initialize(options = {})
67
- invalid_options = options.keys - [:algorithm, :password]
68
- raise ArgumentError, "Unknown key(s): #{invalid_options.join(", ")}" unless invalid_options.empty?
69
-
70
- options = {
71
- :algorithm => SymmetricCipher.default_algorithm,
72
- :password => SymmetricCipher.default_password
73
- }.merge(options)
74
-
75
- self.algorithm = options[:algorithm]
76
- self.password = options[:password]
77
- raise NoPasswordError if password.nil?
78
-
79
- super()
80
- end
81
-
82
- # Decrypts the current string using the current key and algorithm specified
83
- def decrypt(data)
84
- cipher = build_cipher(:decrypt)
85
- cipher.update(Base64.decode64(data)) + cipher.final
86
- end
74
+ self.algorithm = options[:algorithm]
75
+ self.password = options[:password]
76
+ raise NoPasswordError if password.nil?
87
77
 
88
- # Encrypts the current string using the current key and algorithm specified
89
- def encrypt(data)
90
- cipher = build_cipher(:encrypt)
91
- Base64.encode64(cipher.update(data) + cipher.final)
92
- end
93
-
94
- private
95
- def build_cipher(type) #:nodoc:
96
- cipher = OpenSSL::Cipher.new(algorithm).send(type)
97
- cipher.pkcs5_keyivgen(password)
98
- cipher
99
- end
78
+ super()
79
+ end
80
+
81
+ # Decrypts the current string using the current key and algorithm specified
82
+ def decrypt(data)
83
+ cipher = build_cipher(:decrypt)
84
+ cipher.update(Base64.decode64(data)) + cipher.final
100
85
  end
86
+
87
+ # Encrypts the current string using the current key and algorithm specified
88
+ def encrypt(data)
89
+ cipher = build_cipher(:encrypt)
90
+ Base64.encode64(cipher.update(data) + cipher.final)
91
+ end
92
+
93
+ private
94
+ def build_cipher(type) #:nodoc:
95
+ cipher = OpenSSL::Cipher.new(algorithm).send(type)
96
+ cipher.pkcs5_keyivgen(password)
97
+ cipher
98
+ end
101
99
  end
102
100
  end
@@ -2,27 +2,27 @@ require File.dirname(__FILE__) + '/test_helper'
2
2
 
3
3
  class NoPrivateKeyErrorTest < Test::Unit::TestCase
4
4
  def test_should_exist
5
- assert_not_nil PluginAWeek::EncryptedStrings::NoPrivateKeyError
5
+ assert_not_nil EncryptedStrings::NoPrivateKeyError
6
6
  end
7
7
  end
8
8
 
9
9
  class NoPublicKeyErrorTest < Test::Unit::TestCase
10
10
  def test_should_exist
11
- assert_not_nil PluginAWeek::EncryptedStrings::NoPublicKeyError
11
+ assert_not_nil EncryptedStrings::NoPublicKeyError
12
12
  end
13
13
  end
14
14
 
15
15
  class AsymmetricCipherByDefaultTest < Test::Unit::TestCase
16
16
  def setup
17
- @asymmetric_cipher = PluginAWeek::EncryptedStrings::AsymmetricCipher.new(:public_key_file => File.dirname(__FILE__) + '/keys/public')
17
+ @asymmetric_cipher = EncryptedStrings::AsymmetricCipher.new(:public_key_file => File.dirname(__FILE__) + '/keys/public')
18
18
  end
19
19
 
20
20
  def test_should_raise_an_exception
21
- assert_raise(ArgumentError) {PluginAWeek::EncryptedStrings::AsymmetricCipher.new}
21
+ assert_raise(ArgumentError) {EncryptedStrings::AsymmetricCipher.new}
22
22
  end
23
23
 
24
24
  def test_should_not_have_a_public_key_file
25
- @asymmetric_cipher = PluginAWeek::EncryptedStrings::AsymmetricCipher.new(:private_key_file => File.dirname(__FILE__) + '/keys/private')
25
+ @asymmetric_cipher = EncryptedStrings::AsymmetricCipher.new(:private_key_file => File.dirname(__FILE__) + '/keys/private')
26
26
  assert_nil @asymmetric_cipher.public_key_file
27
27
  end
28
28
 
@@ -41,13 +41,13 @@ end
41
41
 
42
42
  class AsymmetricCipherWithCustomDefaultsTest < Test::Unit::TestCase
43
43
  def setup
44
- @original_default_public_key_file = PluginAWeek::EncryptedStrings::AsymmetricCipher.default_public_key_file
45
- @original_default_private_key_file = PluginAWeek::EncryptedStrings::AsymmetricCipher.default_private_key_file
44
+ @original_default_public_key_file = EncryptedStrings::AsymmetricCipher.default_public_key_file
45
+ @original_default_private_key_file = EncryptedStrings::AsymmetricCipher.default_private_key_file
46
46
 
47
- PluginAWeek::EncryptedStrings::AsymmetricCipher.default_public_key_file = File.dirname(__FILE__) + '/keys/public'
48
- PluginAWeek::EncryptedStrings::AsymmetricCipher.default_private_key_file = File.dirname(__FILE__) + '/keys/private'
47
+ EncryptedStrings::AsymmetricCipher.default_public_key_file = File.dirname(__FILE__) + '/keys/public'
48
+ EncryptedStrings::AsymmetricCipher.default_private_key_file = File.dirname(__FILE__) + '/keys/private'
49
49
 
50
- @asymmetric_cipher = PluginAWeek::EncryptedStrings::AsymmetricCipher.new
50
+ @asymmetric_cipher = EncryptedStrings::AsymmetricCipher.new
51
51
  end
52
52
 
53
53
  def test_should_use_default_public_key_file
@@ -67,20 +67,20 @@ class AsymmetricCipherWithCustomDefaultsTest < Test::Unit::TestCase
67
67
  end
68
68
 
69
69
  def teardown
70
- PluginAWeek::EncryptedStrings::AsymmetricCipher.default_public_key_file = @original_default_public_key_file
71
- PluginAWeek::EncryptedStrings::AsymmetricCipher.default_private_key_file = @original_default_private_key_file
70
+ EncryptedStrings::AsymmetricCipher.default_public_key_file = @original_default_public_key_file
71
+ EncryptedStrings::AsymmetricCipher.default_private_key_file = @original_default_private_key_file
72
72
  end
73
73
  end
74
74
 
75
75
  class AsymmetricCipherWithInvalidOptionsTest < Test::Unit::TestCase
76
76
  def test_should_throw_an_exception
77
- assert_raise(ArgumentError) {PluginAWeek::EncryptedStrings::AsymmetricCipher.new(:invalid => true)}
77
+ assert_raise(ArgumentError) {EncryptedStrings::AsymmetricCipher.new(:invalid => true)}
78
78
  end
79
79
  end
80
80
 
81
81
  class AsymmetricCipherTest < Test::Unit::TestCase
82
82
  def setup
83
- @asymmetric_cipher = PluginAWeek::EncryptedStrings::AsymmetricCipher.new(:public_key_file => File.dirname(__FILE__) + '/keys/public')
83
+ @asymmetric_cipher = EncryptedStrings::AsymmetricCipher.new(:public_key_file => File.dirname(__FILE__) + '/keys/public')
84
84
  end
85
85
 
86
86
  def test_should_be_able_to_decrypt
@@ -90,7 +90,7 @@ end
90
90
 
91
91
  class AsymmetricCipherWithoutPublicKeyTest < Test::Unit::TestCase
92
92
  def setup
93
- @asymmetric_cipher = PluginAWeek::EncryptedStrings::AsymmetricCipher.new(:public_key_file => nil, :private_key_file => File.dirname(__FILE__) + '/keys/private')
93
+ @asymmetric_cipher = EncryptedStrings::AsymmetricCipher.new(:public_key_file => nil, :private_key_file => File.dirname(__FILE__) + '/keys/private')
94
94
  end
95
95
 
96
96
  def test_should_not_be_public
@@ -98,13 +98,13 @@ class AsymmetricCipherWithoutPublicKeyTest < Test::Unit::TestCase
98
98
  end
99
99
 
100
100
  def test_should_not_be_able_to_encrypt
101
- assert_raise(PluginAWeek::EncryptedStrings::NoPublicKeyError) {@asymmetric_cipher.encrypt('test')}
101
+ assert_raise(EncryptedStrings::NoPublicKeyError) {@asymmetric_cipher.encrypt('test')}
102
102
  end
103
103
  end
104
104
 
105
105
  class AsymmetricCipherWithPublicKeyTest < Test::Unit::TestCase
106
106
  def setup
107
- @asymmetric_cipher = PluginAWeek::EncryptedStrings::AsymmetricCipher.new(:public_key_file => File.dirname(__FILE__) + '/keys/public')
107
+ @asymmetric_cipher = EncryptedStrings::AsymmetricCipher.new(:public_key_file => File.dirname(__FILE__) + '/keys/public')
108
108
  end
109
109
 
110
110
  def test_should_be_public
@@ -120,13 +120,13 @@ class AsymmetricCipherWithPublicKeyTest < Test::Unit::TestCase
120
120
  end
121
121
 
122
122
  def test_should_not_be_able_to_decrypt
123
- assert_raise(PluginAWeek::EncryptedStrings::NoPrivateKeyError) {@asymmetric_cipher.decrypt("HbEh0Hwri26S7SWYqO26DBbzfhR1h/0pXYLjSKUpxF5DOaOCtD9oRN748+Na\nrfNaVN5Eg7RUhbRFZE+UnNHo6Q==\n")}
123
+ assert_raise(EncryptedStrings::NoPrivateKeyError) {@asymmetric_cipher.decrypt("HbEh0Hwri26S7SWYqO26DBbzfhR1h/0pXYLjSKUpxF5DOaOCtD9oRN748+Na\nrfNaVN5Eg7RUhbRFZE+UnNHo6Q==\n")}
124
124
  end
125
125
  end
126
126
 
127
127
  class AsymmetricCipherWithoutPrivateKeyTest < Test::Unit::TestCase
128
128
  def setup
129
- @asymmetric_cipher = PluginAWeek::EncryptedStrings::AsymmetricCipher.new(:private_key_file => nil, :public_key_file => File.dirname(__FILE__) + '/keys/public')
129
+ @asymmetric_cipher = EncryptedStrings::AsymmetricCipher.new(:private_key_file => nil, :public_key_file => File.dirname(__FILE__) + '/keys/public')
130
130
  end
131
131
 
132
132
  def test_should_not_be_private
@@ -134,13 +134,13 @@ class AsymmetricCipherWithoutPrivateKeyTest < Test::Unit::TestCase
134
134
  end
135
135
 
136
136
  def test_should_not_be_able_to_decrypt
137
- assert_raise(PluginAWeek::EncryptedStrings::NoPrivateKeyError) {@asymmetric_cipher.decrypt("HbEh0Hwri26S7SWYqO26DBbzfhR1h/0pXYLjSKUpxF5DOaOCtD9oRN748+Na\nrfNaVN5Eg7RUhbRFZE+UnNHo6Q==\n")}
137
+ assert_raise(EncryptedStrings::NoPrivateKeyError) {@asymmetric_cipher.decrypt("HbEh0Hwri26S7SWYqO26DBbzfhR1h/0pXYLjSKUpxF5DOaOCtD9oRN748+Na\nrfNaVN5Eg7RUhbRFZE+UnNHo6Q==\n")}
138
138
  end
139
139
  end
140
140
 
141
141
  class AsymmetricCipherWithPrivateKeyTest < Test::Unit::TestCase
142
142
  def setup
143
- @asymmetric_cipher = PluginAWeek::EncryptedStrings::AsymmetricCipher.new(:private_key_file => File.dirname(__FILE__) + '/keys/private')
143
+ @asymmetric_cipher = EncryptedStrings::AsymmetricCipher.new(:private_key_file => File.dirname(__FILE__) + '/keys/private')
144
144
  end
145
145
 
146
146
  def test_should_not_be_public
@@ -152,7 +152,7 @@ class AsymmetricCipherWithPrivateKeyTest < Test::Unit::TestCase
152
152
  end
153
153
 
154
154
  def test_not_should_be_able_to_encrypt
155
- assert_raise(PluginAWeek::EncryptedStrings::NoPublicKeyError) {@asymmetric_cipher.encrypt('test')}
155
+ assert_raise(EncryptedStrings::NoPublicKeyError) {@asymmetric_cipher.encrypt('test')}
156
156
  end
157
157
 
158
158
  def test_should_be_able_to_decrypt
@@ -162,7 +162,7 @@ end
162
162
 
163
163
  class AsymmetricCipherWithEncryptedPrivateKeyTest < Test::Unit::TestCase
164
164
  def setup
165
- @asymmetric_cipher = PluginAWeek::EncryptedStrings::AsymmetricCipher.new(:private_key_file => File.dirname(__FILE__) + '/keys/encrypted_private', :algorithm => 'DES-EDE3-CBC', :password => 'secret')
165
+ @asymmetric_cipher = EncryptedStrings::AsymmetricCipher.new(:private_key_file => File.dirname(__FILE__) + '/keys/encrypted_private', :algorithm => 'DES-EDE3-CBC', :password => 'secret')
166
166
  end
167
167
 
168
168
  def test_should_not_be_public
@@ -174,7 +174,7 @@ class AsymmetricCipherWithEncryptedPrivateKeyTest < Test::Unit::TestCase
174
174
  end
175
175
 
176
176
  def test_should_not_be_able_to_encrypt
177
- assert_raise(PluginAWeek::EncryptedStrings::NoPublicKeyError) {@asymmetric_cipher.encrypt('test')}
177
+ assert_raise(EncryptedStrings::NoPublicKeyError) {@asymmetric_cipher.encrypt('test')}
178
178
  end
179
179
 
180
180
  def test_should_be_able_to_decrypt