encrypted_strings 0.0.1 → 0.0.2
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.
- data/CHANGELOG +15 -0
- data/README +23 -28
- data/Rakefile +3 -3
- data/lib/encrypted_strings/asymmetric_encryptor.rb +57 -17
- data/lib/encrypted_strings/encryptor.rb +18 -17
- data/lib/encrypted_strings/extensions/string.rb +98 -25
- data/lib/encrypted_strings/no_key_error.rb +2 -2
- data/lib/encrypted_strings/no_private_key_error.rb +2 -2
- data/lib/encrypted_strings/no_public_key_error.rb +2 -2
- data/lib/encrypted_strings/sha_encryptor.rb +26 -2
- data/lib/encrypted_strings/symmetric_encryptor.rb +35 -4
- data/test/asymmetric_encryptor_test.rb +5 -5
- data/test/encryptor_test.rb +14 -14
- data/test/string_test.rb +105 -77
- data/test/symmetric_encryptor_test.rb +5 -5
- metadata +24 -23
data/CHANGELOG
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
*SVN*
|
2
|
+
|
3
|
+
*0.0.2* (August 23rd, 2007)
|
4
|
+
|
5
|
+
* Fix not allowing the decryption mode to be overriden if the string already has an encryptor
|
6
|
+
|
7
|
+
* Convert dos newlines to unix newlines
|
8
|
+
|
9
|
+
*0.0.1* (August 5th, 2007)
|
10
|
+
|
11
|
+
* Official public release
|
12
|
+
|
13
|
+
* Add api documentation
|
14
|
+
|
15
|
+
* Refactor unit test names
|
data/README
CHANGED
@@ -12,26 +12,28 @@ Wiki
|
|
12
12
|
|
13
13
|
* http://wiki.pluginaweek.org/Encrypted_strings
|
14
14
|
|
15
|
-
|
15
|
+
Announcement
|
16
16
|
|
17
17
|
* http://www.pluginaweek.org/
|
18
18
|
|
19
|
-
|
19
|
+
Source
|
20
20
|
|
21
21
|
* http://svn.pluginaweek.org/trunk/plugins/ruby/string/encrypted_strings
|
22
22
|
|
23
|
-
|
23
|
+
Development
|
24
24
|
|
25
25
|
* http://dev.pluginaweek.org/browse/trunk/plugins/ruby/string/encrypted_strings
|
26
26
|
|
27
|
-
==
|
27
|
+
== Description
|
28
28
|
|
29
|
-
|
29
|
+
Encrypting and decrypting data is not exactly the most straightforward and DRY
|
30
|
+
way. encrypted_strings greatly improves upon this syntax and adds
|
31
|
+
straightforward support for encrypting values using SHA-1, Symmetric, and
|
32
|
+
Asymmetric modes.
|
30
33
|
|
31
|
-
==
|
34
|
+
== Usage
|
32
35
|
|
33
|
-
|
34
|
-
class, giving you the ability to easily encrypt strings.
|
36
|
+
=== SHA Encryption
|
35
37
|
|
36
38
|
>> password = "shhhh"
|
37
39
|
=> "shhhh"
|
@@ -55,7 +57,7 @@ SHA-1 encryption. For encryption modes that do not support decryption, equality
|
|
55
57
|
with other strings is tested by encrypting the other string and checking whether
|
56
58
|
the resulting encrypted value is the same.
|
57
59
|
|
58
|
-
|
60
|
+
=== Symmetric Encryption
|
59
61
|
|
60
62
|
>> password = "shhhh"
|
61
63
|
=> "shhhh"
|
@@ -70,28 +72,21 @@ If you wanted to use symmetric encryption, you could do so with the following:
|
|
70
72
|
|
71
73
|
=== Asymmetric encryption
|
72
74
|
|
73
|
-
The public and private key file names can be set via the following:
|
74
|
-
|
75
|
-
PluginAWeek::EncryptedStrings::AsymmetricEncryptor.default_public_key_file = "./public.key"
|
76
|
-
PluginAWeek::EncryptedStrings::AsymmetricEncryptor.default_private_key_file = "./private.key"
|
77
|
-
|
78
|
-
== In-place editing
|
79
|
-
|
80
|
-
In addition to generating the encrypted/decrypted strings, you can also
|
81
|
-
replace the original string by using the bang:
|
82
|
-
|
83
75
|
>> password = "shhhh"
|
84
76
|
=> "shhhh"
|
85
|
-
>> password.encrypt
|
86
|
-
=> "
|
87
|
-
>>
|
88
|
-
=>
|
89
|
-
>>
|
90
|
-
=>
|
91
|
-
>> password
|
77
|
+
>> crypted_password = password.encrypt(:asymmetric, :public_key_file => "./public.key", :private_key_file => "./private.key")
|
78
|
+
=> "NEwVzcikYUKfS8HTc9L9eg/dMxBCLZ/nFr7J1aQYjkl3I2MPUD0lmjr/saC6\nTJEPwOl60Ki24H8TUwnGtZy14A==\n"
|
79
|
+
>> crypted_password.class
|
80
|
+
=> String
|
81
|
+
>> crypted_password == "shhhh"
|
82
|
+
=> true
|
83
|
+
>> password = crypted_password.decrypt
|
92
84
|
=> "shhhh"
|
93
85
|
|
86
|
+
== Dependencies
|
87
|
+
|
88
|
+
This plugin does not depend on the presence of any other plugins.
|
89
|
+
|
94
90
|
== References
|
95
91
|
|
96
|
-
|
97
|
-
Much of this plugin's code is based on his work.
|
92
|
+
* Rick Olson - http://svn.techno-weenie.net/projects/plugins/sentry/
|
data/Rakefile
CHANGED
@@ -4,7 +4,7 @@ require 'rake/gempackagetask'
|
|
4
4
|
require 'rake/contrib/sshpublisher'
|
5
5
|
|
6
6
|
PKG_NAME = 'encrypted_strings'
|
7
|
-
PKG_VERSION = '0.0.
|
7
|
+
PKG_VERSION = '0.0.2'
|
8
8
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
9
9
|
RUBY_FORGE_PROJECT = 'pluginaweek'
|
10
10
|
|
@@ -33,7 +33,7 @@ spec = Gem::Specification.new do |s|
|
|
33
33
|
s.platform = Gem::Platform::RUBY
|
34
34
|
s.summary = 'Dead-simple string encryption/decryption syntax.'
|
35
35
|
|
36
|
-
s.files = FileList['{lib,
|
36
|
+
s.files = FileList['{lib,test}/**/*'].to_a + %w(CHANGELOG init.rb MIT-LICENSE Rakefile README)
|
37
37
|
s.require_path = 'lib'
|
38
38
|
s.autorequire = 'encrypted_strings'
|
39
39
|
s.has_rdoc = true
|
@@ -77,4 +77,4 @@ task :release => [:gem, :package] do
|
|
77
77
|
|
78
78
|
ruby_forge.add_release(RUBY_FORGE_PROJECT, PKG_NAME, PKG_VERSION, file)
|
79
79
|
end
|
80
|
-
end
|
80
|
+
end
|
@@ -2,14 +2,52 @@ require 'encrypted_strings/no_private_key_error'
|
|
2
2
|
require 'encrypted_strings/no_public_key_error'
|
3
3
|
|
4
4
|
module PluginAWeek #:nodoc:
|
5
|
-
module EncryptedStrings
|
6
|
-
# Encryption in which the keys used to encrypt/decrypt come in pairs. Also
|
7
|
-
# as public key encryption. Anything that's encrypted using the
|
8
|
-
# only be decrypted with the same algorithm and a matching
|
9
|
-
# Any message that is encrypted with the private key can only
|
10
|
-
# with the matching public key.
|
5
|
+
module EncryptedStrings
|
6
|
+
# Encryption in which the keys used to encrypt/decrypt come in pairs. Also
|
7
|
+
# known as public key encryption. Anything that's encrypted using the
|
8
|
+
# public key can only be decrypted with the same algorithm and a matching
|
9
|
+
# private key. Any message that is encrypted with the private key can only
|
10
|
+
# be decrypted with the matching public key.
|
11
11
|
#
|
12
|
-
# http://support.microsoft.com/kb/246071
|
12
|
+
# Source: http://support.microsoft.com/kb/246071
|
13
|
+
#
|
14
|
+
# == Encrypting
|
15
|
+
#
|
16
|
+
# To encrypt a string using an asymmetric algorithm, the location of the
|
17
|
+
# public key file must be specified. You can define the default for this
|
18
|
+
# value like so:
|
19
|
+
#
|
20
|
+
# PluginAWeek::EncryptedStrings::AsymmetricEncryptor.default_public_key_file = "./public.key"
|
21
|
+
#
|
22
|
+
# If these configuration options are not passed in to #encrypt, then the
|
23
|
+
# default values will be used. You can override the default values like so:
|
24
|
+
#
|
25
|
+
# password = "shhhh"
|
26
|
+
# password.encrypt(:asymmetic, :public_key_file => "./encrypted_public.key") # => "INy95irZ8AlHmvc6ZAF/ARsTpbqPIB/4bEAKKOebjsayB7NYWtIzpswvzxqf\nNJ5yyuvxfMODrcg7RimEMFkFlg==\n"
|
27
|
+
#
|
28
|
+
# An exception will be raised if either the public key file could not be
|
29
|
+
# found or the key could not decrypt the public key file.
|
30
|
+
#
|
31
|
+
# == Decrypting
|
32
|
+
#
|
33
|
+
# To decrypt a string using an asymmetric algorithm, the location of the
|
34
|
+
# private key file must be specified. If this file is itself encrypted, you
|
35
|
+
# must also specify the algorithm and key used to seed the symmetric
|
36
|
+
# algorithm that will decrypt the plublic key file. You can define defaults
|
37
|
+
# for these values like so:
|
38
|
+
#
|
39
|
+
# PluginAWeek::EncryptedStrings::AsymmetricEncryptor.default_private_key_file = "./private.key"
|
40
|
+
# PluginAWeek::EncryptedStrings::SymmetricEncryptor.default_algorithm = "DES-EDE3-CBC"
|
41
|
+
# PluginAWeek::EncryptedStrings::SymmetricEncryptor.default_key = "secret_key"
|
42
|
+
#
|
43
|
+
# If these configuration options are not passed in to #decrypt, then the
|
44
|
+
# default values will be used. You can override the default values like so:
|
45
|
+
#
|
46
|
+
# password = "INy95irZ8AlHmvc6ZAF/ARsTpbqPIB/4bEAKKOebjsayB7NYWtIzpswvzxqf\nNJ5yyuvxfMODrcg7RimEMFkFlg==\n"
|
47
|
+
# password.decrypt(:asymmetic, :public_key_file => "./encrypted_private.key", :key => "secret") # => "shhhh"
|
48
|
+
#
|
49
|
+
# An exception will be raised if either the private key file could not be
|
50
|
+
# found or the key could not decrypt the private key file.
|
13
51
|
class AsymmetricEncryptor < Encryptor
|
14
52
|
# The default private key to use during encryption. Default is nil.
|
15
53
|
@@default_private_key_file = nil
|
@@ -100,7 +138,7 @@ module PluginAWeek #:nodoc:
|
|
100
138
|
end
|
101
139
|
|
102
140
|
private
|
103
|
-
def load_private_key
|
141
|
+
def load_private_key
|
104
142
|
@private_rsa = nil
|
105
143
|
|
106
144
|
if @private_key_file && File.file?(@private_key_file)
|
@@ -108,7 +146,7 @@ module PluginAWeek #:nodoc:
|
|
108
146
|
end
|
109
147
|
end
|
110
148
|
|
111
|
-
def load_public_key
|
149
|
+
def load_public_key
|
112
150
|
@public_rsa = nil
|
113
151
|
|
114
152
|
if @public_key_file && File.file?(@public_key_file)
|
@@ -116,18 +154,20 @@ module PluginAWeek #:nodoc:
|
|
116
154
|
end
|
117
155
|
end
|
118
156
|
|
119
|
-
# Retrieves private RSA from the
|
120
|
-
def private_rsa
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
157
|
+
# Retrieves private RSA from the private key
|
158
|
+
def private_rsa
|
159
|
+
if @key
|
160
|
+
private_key = @private_key.decrypt(:symmetric, :key => @key, :algorithm => @algorithm)
|
161
|
+
OpenSSL::PKey::RSA.new(private_key)
|
162
|
+
else
|
163
|
+
@private_rsa ||= OpenSSL::PKey::RSA.new(@private_key)
|
164
|
+
end
|
125
165
|
end
|
126
166
|
|
127
167
|
# Retrieves the public RSA
|
128
|
-
def public_rsa
|
168
|
+
def public_rsa
|
129
169
|
@public_rsa ||= OpenSSL::PKey::RSA.new(@public_key)
|
130
170
|
end
|
131
171
|
end
|
132
172
|
end
|
133
|
-
end
|
173
|
+
end
|
@@ -1,17 +1,18 @@
|
|
1
|
-
module PluginAWeek #:nodoc:
|
2
|
-
module EncryptedStrings
|
3
|
-
# Represents an encryptor for strings. Certain encryption algorithms
|
4
|
-
# do not allow for strings to be decrypted.
|
5
|
-
class Encryptor
|
6
|
-
# Can this string be decrypted?
|
7
|
-
def can_decrypt?
|
8
|
-
true
|
9
|
-
end
|
10
|
-
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
1
|
+
module PluginAWeek #:nodoc:
|
2
|
+
module EncryptedStrings
|
3
|
+
# Represents an encryptor for strings. Certain encryption algorithms
|
4
|
+
# do not allow for strings to be decrypted.
|
5
|
+
class Encryptor
|
6
|
+
# Can this string be decrypted? Default is true.
|
7
|
+
def can_decrypt?
|
8
|
+
true
|
9
|
+
end
|
10
|
+
|
11
|
+
# Attempts to decrypt the given data using the current configuration. By
|
12
|
+
# default, decryption is not implemented.
|
13
|
+
def decrypt(data)
|
14
|
+
raise NotImplementedError, "Decryption is not supported using a(n) #{self.class.name}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -2,9 +2,9 @@ require 'openssl'
|
|
2
2
|
require 'base64'
|
3
3
|
|
4
4
|
module PluginAWeek #:nodoc:
|
5
|
-
module EncryptedStrings
|
5
|
+
module EncryptedStrings
|
6
6
|
module Extensions #:nodoc:
|
7
|
-
# Adds encryption/decryption
|
7
|
+
# Adds support for encryption/decryption of strings
|
8
8
|
module String
|
9
9
|
def self.included(base) #:nodoc:
|
10
10
|
base.class_eval do
|
@@ -15,19 +15,36 @@ module PluginAWeek #:nodoc:
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
# Encrypts
|
19
|
-
def encrypt!(*args)
|
20
|
-
encrypted_string = encrypt(*args)
|
21
|
-
self.encryptor = encrypted_string.encryptor
|
22
|
-
|
23
|
-
replace(encrypted_string)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Encrypts the current string using the encryption algorithm specified.
|
18
|
+
# Encrypts the current string using the specified encryption mode.
|
27
19
|
# The default encryption mode is sha.
|
28
20
|
#
|
29
|
-
# Configuration options are encryption-
|
30
|
-
# class for that
|
21
|
+
# Configuration options are encryption-specific. See the encryptor
|
22
|
+
# class for that mode to find out the options available.
|
23
|
+
#
|
24
|
+
# == Example
|
25
|
+
#
|
26
|
+
# The following uses SHA mode to encrypt the string:
|
27
|
+
#
|
28
|
+
# password = "shhhh"
|
29
|
+
# password.encrypt # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
|
30
|
+
#
|
31
|
+
# == Custom encryption mode
|
32
|
+
#
|
33
|
+
# The following uses Symmetric mode (with a default key) to encrypt the
|
34
|
+
# string:
|
35
|
+
#
|
36
|
+
# PluginAWeek::EncryptedStrings::SymmetricEncryptor.default_key = "my_key"
|
37
|
+
# password = "shhhh"
|
38
|
+
# password.encrypt(:symmetric) # => "jDACXI5hMPI=\n"
|
39
|
+
#
|
40
|
+
# == Custom encryption options
|
41
|
+
#
|
42
|
+
# Some encryption modes also support additional configuration options
|
43
|
+
# that determine how to encrypt the string. For example, SHA supports
|
44
|
+
# a salt which seeds the algorithm:
|
45
|
+
#
|
46
|
+
# password = "shhhh"
|
47
|
+
# password.encrypt(:sha, :salt => "secret") # => "3b22cbe4acde873c3efc82681096f3ae69aff828"
|
31
48
|
def encrypt(*args)
|
32
49
|
encryptor = encryptor_from_args(*args)
|
33
50
|
encrypted_string = encryptor.encrypt(self)
|
@@ -36,14 +53,33 @@ module PluginAWeek #:nodoc:
|
|
36
53
|
encrypted_string
|
37
54
|
end
|
38
55
|
|
39
|
-
#
|
40
|
-
|
41
|
-
|
56
|
+
# Encrypts this string and replaces it with the encrypted value. This
|
57
|
+
# takes the same parameters as #encrypt, but returns the same string
|
58
|
+
# instead of a different one.
|
59
|
+
#
|
60
|
+
# For example,
|
61
|
+
#
|
62
|
+
# password = "shhhh"
|
63
|
+
# password.encrypt!(:symmetric, :key => "my_key") # => "jDACXI5hMPI=\n"
|
64
|
+
# password # => "jDACXI5hMPI=\n"
|
65
|
+
def encrypt!(*args)
|
66
|
+
encrypted_string = encrypt(*args)
|
67
|
+
self.encryptor = encrypted_string.encryptor
|
68
|
+
|
69
|
+
replace(encrypted_string)
|
42
70
|
end
|
43
71
|
|
44
|
-
#
|
45
|
-
|
46
|
-
|
72
|
+
# Is this string encrypted? This will return true if the string is the
|
73
|
+
# result of a call to #encrypt or #encrypt! was previously invoked.
|
74
|
+
#
|
75
|
+
# For example,
|
76
|
+
#
|
77
|
+
# password = "shhhh"
|
78
|
+
# password.encrypted? # => false
|
79
|
+
# password.encrypt! # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
|
80
|
+
# password.encrypted? # => true
|
81
|
+
def encrypted?
|
82
|
+
!@encryptor.nil?
|
47
83
|
end
|
48
84
|
|
49
85
|
# Decrypts this string. If this is not a string that was previously encrypted,
|
@@ -52,18 +88,55 @@ module PluginAWeek #:nodoc:
|
|
52
88
|
def decrypt(*args)
|
53
89
|
raise ArgumentError, "An encrypt algorithm must be specified since we can't figure it out" if args.empty? && !@encryptor
|
54
90
|
|
55
|
-
encryptor = @encryptor || encryptor_from_args(*args)
|
56
|
-
encryptor.decrypt(self)
|
91
|
+
encryptor = args.any? ? encryptor_from_args(*args) : (@encryptor || encryptor_from_args(*args))
|
92
|
+
encrypted_string = encryptor.decrypt(self)
|
93
|
+
encrypted_string.encryptor = nil
|
94
|
+
|
95
|
+
encrypted_string
|
57
96
|
end
|
58
97
|
|
59
|
-
#
|
98
|
+
# Decrypts this string and replaces it with the decrypted value This
|
99
|
+
# takes the same parameters as #decrypt, but returns the same string
|
100
|
+
# instead of a different one.
|
101
|
+
#
|
102
|
+
# For example,
|
103
|
+
#
|
104
|
+
# password = "jDACXI5hMPI=\n"
|
105
|
+
# password.decrypt!(:symmetric, :key => "my_key") # => "shhhh"
|
106
|
+
# password # => "shhhh"
|
107
|
+
def decrypt!(*args)
|
108
|
+
replace(decrypt(*args))
|
109
|
+
end
|
110
|
+
|
111
|
+
# Can this string be decrypted? Strings can only be decrypted if they
|
112
|
+
# have previously been decrypted +and+ the encryption algorithm supports
|
113
|
+
# decryption. To determine whether or not the encryption algorithm
|
114
|
+
# supports decryption, see the api for the algorithm's encryptor class.
|
60
115
|
def can_decrypt?
|
61
|
-
|
116
|
+
encrypted? && @encryptor.can_decrypt?
|
62
117
|
end
|
63
118
|
|
64
119
|
# Tests whether the other object is equal to this one. Encrypted strings
|
65
120
|
# will be tested not only on their encrypted strings, but also by
|
66
|
-
# decrypting them and running tests against the decrypted value
|
121
|
+
# decrypting them and running tests against the decrypted value.
|
122
|
+
#
|
123
|
+
# == Equality with strings
|
124
|
+
#
|
125
|
+
# password = "shhhh"
|
126
|
+
# password.encrypt! # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
|
127
|
+
# password # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
|
128
|
+
# password == "shhhh" # => true
|
129
|
+
#
|
130
|
+
# == Equality with encrypted strings
|
131
|
+
#
|
132
|
+
# password = "shhhh"
|
133
|
+
# password.encrypt! # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
|
134
|
+
# password # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
|
135
|
+
# password == "shhhh" # => true
|
136
|
+
#
|
137
|
+
# another_password = "shhhh"
|
138
|
+
# another_password.encrypt! # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
|
139
|
+
# password == another_password # => true
|
67
140
|
def equals_with_encryption(other)
|
68
141
|
if !(is_equal = equals_without_encryption(other)) && String === other
|
69
142
|
if encrypted?
|
@@ -105,4 +178,4 @@ end
|
|
105
178
|
|
106
179
|
::String.class_eval do
|
107
180
|
include PluginAWeek::EncryptedStrings::Extensions::String
|
108
|
-
end
|
181
|
+
end
|
@@ -1,8 +1,32 @@
|
|
1
1
|
require 'digest/sha1'
|
2
2
|
|
3
3
|
module PluginAWeek #:nodoc:
|
4
|
-
module EncryptedStrings
|
4
|
+
module EncryptedStrings
|
5
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 algorithm, the salt used to seed the
|
10
|
+
# encrypting must be specified. You can define the default for this
|
11
|
+
# value like so:
|
12
|
+
#
|
13
|
+
# PluginAWeek::EncryptedStrings::ShaEncryptor.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 => "my_salt") # => "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,
|
26
|
+
#
|
27
|
+
# password = "shhhh".encrypt(:sha, :salt => "secret") # => "3b22cbe4acde873c3efc82681096f3ae69aff828"
|
28
|
+
# input = "shhhh".encrypt(:sha, :salt => "secret") # => "3b22cbe4acde873c3efc82681096f3ae69aff828"
|
29
|
+
# password == input # => true
|
6
30
|
class ShaEncryptor < Encryptor
|
7
31
|
# The default salt value to use during encryption
|
8
32
|
@@default_salt = 'salt'
|
@@ -32,4 +56,4 @@ module PluginAWeek #:nodoc:
|
|
32
56
|
end
|
33
57
|
end
|
34
58
|
end
|
35
|
-
end
|
59
|
+
end
|
@@ -1,12 +1,43 @@
|
|
1
1
|
require 'encrypted_strings/no_key_error'
|
2
2
|
|
3
3
|
module PluginAWeek #:nodoc:
|
4
|
-
module EncryptedStrings
|
4
|
+
module EncryptedStrings
|
5
5
|
# Symmetric encryption uses a key and a specific algorithm to encrypt the
|
6
6
|
# string. As long as the key and algorithm are known, the string can be
|
7
7
|
# decrypted.
|
8
8
|
#
|
9
|
-
# http://support.microsoft.com/kb/246071
|
9
|
+
# Source: http://support.microsoft.com/kb/246071
|
10
|
+
#
|
11
|
+
# == Encrypting
|
12
|
+
#
|
13
|
+
# To encrypt a string using a symmetric algorithm, the type of algorithm and
|
14
|
+
# key must be specified. You can define the defaults for these values like
|
15
|
+
# so:
|
16
|
+
#
|
17
|
+
# PluginAWeek::EncryptedStrings::SymmetricEncryptor.default_algorithm = "des-ecb"
|
18
|
+
# PluginAWeek::EncryptedStrings::SymmetricEncryptor.default_key = "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(:symmetic, :algorithm => "des-ecb", :key => "secret") # => "sUG6tYSn0mI=\n"
|
25
|
+
#
|
26
|
+
# An exception will be raised if no key is specified.
|
27
|
+
#
|
28
|
+
# == Decrypting
|
29
|
+
#
|
30
|
+
# To decrypt a string using an symmetric algorithm, the type of algorithm
|
31
|
+
# and key must also be specified. Defaults for these values can be defined
|
32
|
+
# 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 = "sUG6tYSn0mI=\n"
|
38
|
+
# password.decrypt(:symmetic, :algorithm => "des-ecb", :key => "secret") # => "shhhh"
|
39
|
+
#
|
40
|
+
# An exception will be raised if no key is specified.
|
10
41
|
class SymmetricEncryptor < Encryptor
|
11
42
|
# The default algorithm to use for encryption. Default is DES
|
12
43
|
@@default_algorithm = 'DES-EDE3-CBC'
|
@@ -29,7 +60,7 @@ module PluginAWeek #:nodoc:
|
|
29
60
|
:algorithm
|
30
61
|
)
|
31
62
|
options.reverse_merge!(:key => @@default_key)
|
32
|
-
options[:algorithm] ||= @@default_algorithm
|
63
|
+
options[:algorithm] ||= @@default_algorithm
|
33
64
|
|
34
65
|
@key = options[:key]
|
35
66
|
raise NoKeyError if @key.nil?
|
@@ -61,4 +92,4 @@ module PluginAWeek #:nodoc:
|
|
61
92
|
end
|
62
93
|
end
|
63
94
|
end
|
64
|
-
end
|
95
|
+
end
|
@@ -34,7 +34,7 @@ class AsymmetricEncryptorTest < Test::Unit::TestCase
|
|
34
34
|
assert encryptor.public?
|
35
35
|
assert encryptor.private?
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def test_should_read_encrypted_key_files
|
39
39
|
encryptor = PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new(
|
40
40
|
:public_key_file => @encrypted_public_key_file,
|
@@ -43,7 +43,7 @@ class AsymmetricEncryptorTest < Test::Unit::TestCase
|
|
43
43
|
assert encryptor.public?
|
44
44
|
assert encryptor.private?
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
def test_should_decrypt_files
|
48
48
|
encryptor = PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new(
|
49
49
|
:public_key_file => @public_key_file,
|
@@ -52,7 +52,7 @@ class AsymmetricEncryptorTest < Test::Unit::TestCase
|
|
52
52
|
|
53
53
|
assert_equal @data, encryptor.decrypt(@encrypted_data)
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
def test_should_decrypt_files_with_encrypted_key
|
57
57
|
encryptor = PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new(
|
58
58
|
:public_key_file => @encrypted_public_key_file,
|
@@ -62,7 +62,7 @@ class AsymmetricEncryptorTest < Test::Unit::TestCase
|
|
62
62
|
|
63
63
|
assert_equal @data, encryptor.decrypt(@encrypted_data_with_encrypted_keys)
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
def test_should_decrypt_files_with_default_key
|
67
67
|
set_default_key_files @public_key_file, @private_key_file
|
68
68
|
assert_equal @data, PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new.decrypt(@encrypted_data)
|
@@ -94,4 +94,4 @@ class AsymmetricEncryptorTest < Test::Unit::TestCase
|
|
94
94
|
PluginAWeek::EncryptedStrings::AsymmetricEncryptor.default_public_key_file = public_key
|
95
95
|
PluginAWeek::EncryptedStrings::AsymmetricEncryptor.default_private_key_file = private_key
|
96
96
|
end
|
97
|
-
end
|
97
|
+
end
|
data/test/encryptor_test.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
-
|
3
|
-
class EncryptorTest < Test::Unit::TestCase
|
4
|
-
def setup
|
5
|
-
@encryptor = PluginAWeek::EncryptedStrings::Encryptor.new
|
6
|
-
end
|
7
|
-
|
8
|
-
def test_should_be_able_to_decrypt_by_default
|
9
|
-
assert @encryptor.can_decrypt?
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_should_raise_exception_if_decrypt_not_implemented
|
13
|
-
assert_raises(NotImplementedError) { @encryptor.decrypt('test') }
|
14
|
-
end
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class EncryptorTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@encryptor = PluginAWeek::EncryptedStrings::Encryptor.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_should_be_able_to_decrypt_by_default
|
9
|
+
assert @encryptor.can_decrypt?
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_should_raise_exception_if_decrypt_not_implemented
|
13
|
+
assert_raises(NotImplementedError) { @encryptor.decrypt('test') }
|
14
|
+
end
|
15
15
|
end
|
data/test/string_test.rb
CHANGED
@@ -1,77 +1,105 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
-
|
3
|
-
class EncryptedStringsTest < Test::Unit::TestCase
|
4
|
-
def test_should_use_sha_for_default_encryption
|
5
|
-
assert_instance_of PluginAWeek::EncryptedStrings::ShaEncryptor, 'test'.encrypt.encryptor
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
encrypted_string.
|
37
|
-
|
38
|
-
assert !
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
assert_equal
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class EncryptedStringsTest < Test::Unit::TestCase
|
4
|
+
def test_should_use_sha_for_default_encryption
|
5
|
+
assert_instance_of PluginAWeek::EncryptedStrings::ShaEncryptor, 'test'.encrypt.encryptor
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_should_use_configuration_options_for_default_encryption
|
9
|
+
encrypted_string = 'test'.encrypt(:salt => 'different_salt')
|
10
|
+
assert_instance_of PluginAWeek::EncryptedStrings::ShaEncryptor, encrypted_string.encryptor
|
11
|
+
assert_equal 'different_salt', encrypted_string.encryptor.salt
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_should_use_custom_encryptor_if_mode_specified
|
15
|
+
encrypted_string = 'test'.encrypt(:symmetric, :key => 'key')
|
16
|
+
assert_instance_of PluginAWeek::EncryptedStrings::SymmetricEncryptor, encrypted_string.encryptor
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_should_replace_string_with_bang_encryption
|
20
|
+
encrypted_string = 'test'
|
21
|
+
encrypted_string.encrypt!
|
22
|
+
|
23
|
+
assert !'test'.equals_without_encryption(encrypted_string)
|
24
|
+
assert_instance_of PluginAWeek::EncryptedStrings::ShaEncryptor, encrypted_string.encryptor
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_should_be_encrypted_if_string_has_been_encrypted
|
28
|
+
assert 'test'.encrypt.encrypted?
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_not_be_encrypted_if_string_has_not_been_encrypted
|
32
|
+
assert !'test'.encrypted?
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_should_not_be_encrypted_after_being_decrypted
|
36
|
+
encrypted_string = 'test'.encrypt(:symmetric, :key => 'secret')
|
37
|
+
decrypted_string = encrypted_string.decrypt
|
38
|
+
assert !decrypted_string.encrypted?
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_should_use_encryptor_for_decryption_by_default
|
42
|
+
encrypted_string = 'test'.encrypt(:symmetric, :key => 'secret')
|
43
|
+
assert 'test'.equals_without_encryption(encrypted_string.decrypt)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_should_allow_custom_mode_when_decrypting
|
47
|
+
assert_equal 'test', "MU6e/5LvhKA=\n".decrypt(:symmetric, :key => 'secret')
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_should_replace_string_with_bang_decryption
|
51
|
+
encrypted_string = "MU6e/5LvhKA=\n"
|
52
|
+
encrypted_string.decrypt!(:symmetric, :key => 'secret')
|
53
|
+
|
54
|
+
assert !"MU6e/5LvhKA=\n".equals_without_encryption(encrypted_string)
|
55
|
+
assert 'test'.equals_without_encryption(encrypted_string)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_should_be_able_to_decrypt_if_encryptor_can_decrypt
|
59
|
+
assert 'test'.encrypt(:symmetric, :key => 'secret').can_decrypt?
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_should_not_be_able_to_decrypt_if_encryptor_cant_decrypt
|
63
|
+
assert !'test'.encrypt(:sha).can_decrypt?
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_should_not_be_able_to_decrypt_if_never_encrypted
|
67
|
+
assert !'test'.can_decrypt?
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_should_be_able_to_check_equality_without_decryption_support
|
71
|
+
value = 'test'
|
72
|
+
encrypted_string = 'test'.encrypt(:sha)
|
73
|
+
encrypted_encrypted_string = encrypted_string.encrypt(:sha)
|
74
|
+
|
75
|
+
assert_equal value, encrypted_string
|
76
|
+
assert_equal encrypted_string, value
|
77
|
+
assert_equal encrypted_string, encrypted_encrypted_string
|
78
|
+
assert_equal encrypted_encrypted_string, encrypted_string
|
79
|
+
assert_equal encrypted_string.to_s, encrypted_string
|
80
|
+
assert_equal encrypted_string, encrypted_string.to_s
|
81
|
+
assert_equal encrypted_string, encrypted_string
|
82
|
+
|
83
|
+
assert_not_equal value, encrypted_encrypted_string
|
84
|
+
assert_not_equal encrypted_encrypted_string, value
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_should_be_able_to_check_equality_with_decryption_support
|
88
|
+
PluginAWeek::EncryptedStrings::SymmetricEncryptor.default_key = 'secret'
|
89
|
+
|
90
|
+
value = 'test'
|
91
|
+
encrypted_string = value.encrypt(:symmetric)
|
92
|
+
encrypted_encrypted_string = encrypted_string.encrypt(:symmetric)
|
93
|
+
|
94
|
+
assert_equal value, encrypted_string
|
95
|
+
assert_equal encrypted_string, value
|
96
|
+
assert_equal encrypted_string, encrypted_encrypted_string
|
97
|
+
assert_equal encrypted_encrypted_string, encrypted_string
|
98
|
+
assert_equal encrypted_string.to_s, encrypted_string
|
99
|
+
assert_equal encrypted_string, encrypted_string.to_s
|
100
|
+
assert_equal encrypted_string, encrypted_string
|
101
|
+
|
102
|
+
assert_not_equal value, encrypted_encrypted_string
|
103
|
+
assert_not_equal encrypted_encrypted_string, value
|
104
|
+
end
|
105
|
+
end
|
@@ -12,15 +12,15 @@ class SymmetricallyEncryptedStringTest < Test::Unit::TestCase
|
|
12
12
|
assert_raises(PluginAWeek::EncryptedStrings::NoKeyError) { PluginAWeek::EncryptedStrings::SymmetricEncryptor.new }
|
13
13
|
end
|
14
14
|
|
15
|
-
def test_should_encrypt_with_custom_key_if_key_specified
|
16
|
-
assert_equal @encrypted, PluginAWeek::EncryptedStrings::SymmetricEncryptor.new(:key => @key).encrypt(@data)
|
17
|
-
end
|
18
|
-
|
19
15
|
def test_encrypt_with_default_key_if_key_not_specified
|
20
16
|
PluginAWeek::EncryptedStrings::SymmetricEncryptor.default_key = @key
|
21
17
|
assert_equal @encrypted, PluginAWeek::EncryptedStrings::SymmetricEncryptor.new.encrypt(@data)
|
22
18
|
end
|
23
19
|
|
20
|
+
def test_should_encrypt_with_custom_key_if_key_specified
|
21
|
+
assert_equal @encrypted, PluginAWeek::EncryptedStrings::SymmetricEncryptor.new(:key => @key).encrypt(@data)
|
22
|
+
end
|
23
|
+
|
24
24
|
def test_should_be_able_to_decrypt
|
25
25
|
assert PluginAWeek::EncryptedStrings::SymmetricEncryptor.new(:key => @key).can_decrypt?
|
26
26
|
end
|
@@ -33,4 +33,4 @@ class SymmetricallyEncryptedStringTest < Test::Unit::TestCase
|
|
33
33
|
PluginAWeek::EncryptedStrings::SymmetricEncryptor.default_key = @key
|
34
34
|
assert_equal @data, PluginAWeek::EncryptedStrings::SymmetricEncryptor.new.decrypt(@encrypted)
|
35
35
|
end
|
36
|
-
end
|
36
|
+
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.0
|
3
3
|
specification_version: 1
|
4
4
|
name: encrypted_strings
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2007-08-
|
6
|
+
version: 0.0.2
|
7
|
+
date: 2007-08-23 00:00:00 -04:00
|
8
8
|
summary: Dead-simple string encryption/decryption syntax.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -29,44 +29,45 @@ post_install_message:
|
|
29
29
|
authors:
|
30
30
|
- Aaron Pfeifer, Neil Abraham
|
31
31
|
files:
|
32
|
+
- lib/encrypted_strings.rb
|
32
33
|
- lib/encrypted_strings
|
33
|
-
- lib/encrypted_strings/asymmetric_encryptor.rb
|
34
|
-
- lib/encrypted_strings/encryptor.rb
|
35
34
|
- lib/encrypted_strings/extensions
|
36
|
-
- lib/encrypted_strings/
|
37
|
-
- lib/encrypted_strings/no_key_error.rb
|
38
|
-
- lib/encrypted_strings/no_private_key_error.rb
|
35
|
+
- lib/encrypted_strings/asymmetric_encryptor.rb
|
39
36
|
- lib/encrypted_strings/no_public_key_error.rb
|
37
|
+
- lib/encrypted_strings/no_key_error.rb
|
40
38
|
- lib/encrypted_strings/sha_encryptor.rb
|
39
|
+
- lib/encrypted_strings/no_private_key_error.rb
|
40
|
+
- lib/encrypted_strings/encryptor.rb
|
41
41
|
- lib/encrypted_strings/symmetric_encryptor.rb
|
42
|
-
- lib/encrypted_strings.rb
|
43
|
-
- test/
|
44
|
-
- test/encryptor_test.rb
|
45
|
-
- test/keys
|
46
|
-
- test/keys/encrypted_private
|
47
|
-
- test/keys/encrypted_public
|
48
|
-
- test/keys/private
|
49
|
-
- test/keys/public
|
50
|
-
- test/no_key_error_test.rb
|
42
|
+
- lib/encrypted_strings/extensions/string.rb
|
43
|
+
- test/test_helper.rb
|
51
44
|
- test/no_private_key_error_test.rb
|
52
45
|
- test/no_public_key_error_test.rb
|
53
46
|
- test/sha_encryptor_test.rb
|
54
|
-
- test/string_test.rb
|
55
47
|
- test/symmetric_encryptor_test.rb
|
56
|
-
- test/
|
48
|
+
- test/string_test.rb
|
49
|
+
- test/encryptor_test.rb
|
50
|
+
- test/asymmetric_encryptor_test.rb
|
51
|
+
- test/keys
|
52
|
+
- test/no_key_error_test.rb
|
53
|
+
- test/keys/private
|
54
|
+
- test/keys/public
|
55
|
+
- test/keys/encrypted_public
|
56
|
+
- test/keys/encrypted_private
|
57
|
+
- CHANGELOG
|
57
58
|
- init.rb
|
58
59
|
- MIT-LICENSE
|
59
60
|
- Rakefile
|
60
61
|
- README
|
61
62
|
test_files:
|
62
|
-
- test/asymmetric_encryptor_test.rb
|
63
|
-
- test/encryptor_test.rb
|
64
|
-
- test/no_key_error_test.rb
|
65
63
|
- test/no_private_key_error_test.rb
|
66
64
|
- test/no_public_key_error_test.rb
|
67
65
|
- test/sha_encryptor_test.rb
|
68
|
-
- test/string_test.rb
|
69
66
|
- test/symmetric_encryptor_test.rb
|
67
|
+
- test/string_test.rb
|
68
|
+
- test/encryptor_test.rb
|
69
|
+
- test/asymmetric_encryptor_test.rb
|
70
|
+
- test/no_key_error_test.rb
|
70
71
|
rdoc_options: []
|
71
72
|
|
72
73
|
extra_rdoc_files: []
|