encrypted_strings 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2005 Rick Olson, 2006-2007 Aaron Pfeifer & Neil Abraham
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,97 @@
1
+ = encrypted_strings
2
+
3
+ encrypted_strings provides dead-simple string encryption/decryption syntax.
4
+
5
+ == Resources
6
+
7
+ API
8
+
9
+ * http://api.pluginaweek.org/encrypted_strings
10
+
11
+ Wiki
12
+
13
+ * http://wiki.pluginaweek.org/Encrypted_strings
14
+
15
+ Blog
16
+
17
+ * http://www.pluginaweek.org/
18
+
19
+ Subversion
20
+
21
+ * http://svn.pluginaweek.org/trunk/plugins/ruby/string/encrypted_strings
22
+
23
+ Trac
24
+
25
+ * http://dev.pluginaweek.org/browse/trunk/plugins/ruby/string/encrypted_strings
26
+
27
+ == Types of encryption supported
28
+
29
+ This plugin supports Hashed, Symmetric, and Asymmetric encryption modes.
30
+
31
+ == How to use
32
+
33
+ This plugin adds the method 'encrypt' and other supporting methods to the String
34
+ class, giving you the ability to easily encrypt strings.
35
+
36
+ >> password = "shhhh"
37
+ => "shhhh"
38
+ >> crypted_password = password.encrypt
39
+ => "66c85d26dadde7e1db27e15a0776c921e27143bd"
40
+ >> crypted_password.class
41
+ => String
42
+ >> crypted_password.encryptor
43
+ => #<PluginAWeek::EncryptedStrings::ShaEncryptor:0x2b9238889460 @salt="salt">
44
+ >> crypted_password == "shhhh"
45
+ => true
46
+ >> crypted_password.decrypt
47
+ NotImplementedError: Decryption is not supported using a(n) PluginAWeek::EncryptedStrings::ShaEncryptor
48
+ from ./script/../config/../config/../vendor/plugins/encrypted_strings/lib/encrypted_strings/encryptor.rb:13:in `decrypt'
49
+ from ./script/../config/../config/../vendor/plugins/encrypted_strings/lib/encrypted_strings/extensions/string.rb:52:in `decrypt'
50
+ from (irb):40
51
+
52
+ When encrypt is called, it creates an encryptor instance which is used for
53
+ future encryption and decryption of the string. The default encryptor uses
54
+ SHA-1 encryption. For encryption modes that do not support decryption, equality
55
+ with other strings is tested by encrypting the other string and checking whether
56
+ the resulting encrypted value is the same.
57
+
58
+ If you wanted to use symmetric encryption, you could do so with the following:
59
+
60
+ >> password = "shhhh"
61
+ => "shhhh"
62
+ >> crypted_password = password.encrypt(:symmetric, :key => "my_key")
63
+ => "jDACXI5hMPI=\n"
64
+ >> crypted_password.class
65
+ => String
66
+ >> crypted_password == "shhhh"
67
+ => true
68
+ >> password = crypted_password.decrypt
69
+ => "shhhh"
70
+
71
+ === Asymmetric encryption
72
+
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
+ >> password = "shhhh"
84
+ => "shhhh"
85
+ >> password.encrypt!(:symmetric, :key => "my_key")
86
+ => "jDACXI5hMPI=\n"
87
+ >> password
88
+ => "jDACXI5hMPI=\n"
89
+ >> password.decrypt!
90
+ => "shhhh"
91
+ >> password
92
+ => "shhhh"
93
+
94
+ == References
95
+
96
+ A huge thanks to Rick Olson and his Sentry plugin over at http://svn.techno-weenie.net/projects/plugins/sentry/.
97
+ Much of this plugin's code is based on his work.
data/Rakefile ADDED
@@ -0,0 +1,80 @@
1
+ require 'rake/testtask'
2
+ require 'rake/rdoctask'
3
+ require 'rake/gempackagetask'
4
+ require 'rake/contrib/sshpublisher'
5
+
6
+ PKG_NAME = 'encrypted_strings'
7
+ PKG_VERSION = '0.0.1'
8
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
9
+ RUBY_FORGE_PROJECT = 'pluginaweek'
10
+
11
+ desc 'Default: run unit tests.'
12
+ task :default => :test
13
+
14
+ desc 'Test the encrypted_strings plugin.'
15
+ Rake::TestTask.new(:test) do |t|
16
+ t.libs << 'lib'
17
+ t.pattern = 'test/**/*_test.rb'
18
+ t.verbose = true
19
+ end
20
+
21
+ desc 'Generate documentation for the encrypted_strings plugin.'
22
+ Rake::RDocTask.new(:rdoc) do |rdoc|
23
+ rdoc.rdoc_dir = 'rdoc'
24
+ rdoc.title = 'EncryptedStrings'
25
+ rdoc.options << '--line-numbers' << '--inline-source'
26
+ rdoc.rdoc_files.include('README')
27
+ rdoc.rdoc_files.include('lib/**/*.rb')
28
+ end
29
+
30
+ spec = Gem::Specification.new do |s|
31
+ s.name = PKG_NAME
32
+ s.version = PKG_VERSION
33
+ s.platform = Gem::Platform::RUBY
34
+ s.summary = 'Dead-simple string encryption/decryption syntax.'
35
+
36
+ s.files = FileList['{lib,tasks,test}/**/*'].to_a + %w(init.rb MIT-LICENSE Rakefile README)
37
+ s.require_path = 'lib'
38
+ s.autorequire = 'encrypted_strings'
39
+ s.has_rdoc = true
40
+ s.test_files = Dir['test/**/*_test.rb']
41
+ s.add_dependency 'activesupport', '>= 1.3.1'
42
+
43
+ s.author = 'Aaron Pfeifer, Neil Abraham'
44
+ s.email = 'info@pluginaweek.org'
45
+ s.homepage = 'http://www.pluginaweek.org'
46
+ end
47
+
48
+ Rake::GemPackageTask.new(spec) do |p|
49
+ p.gem_spec = spec
50
+ p.need_tar = true
51
+ p.need_zip = true
52
+ end
53
+
54
+ desc 'Publish the beta gem'
55
+ task :pgem => [:package] do
56
+ Rake::SshFilePublisher.new('pluginaweek@pluginaweek.org', '/home/pluginaweek/gems.pluginaweek.org/gems', 'pkg', "#{PKG_FILE_NAME}.gem").upload
57
+ end
58
+
59
+ desc 'Publish the API documentation'
60
+ task :pdoc => [:rdoc] do
61
+ Rake::SshDirPublisher.new('pluginaweek@pluginaweek.org', "/home/pluginaweek/api.pluginaweek.org/#{PKG_NAME}", 'rdoc').upload
62
+ end
63
+
64
+ desc 'Publish the API docs and gem'
65
+ task :publish => [:pdoc, :release]
66
+
67
+ desc 'Publish the release files to RubyForge.'
68
+ task :release => [:gem, :package] do
69
+ require 'rubyforge'
70
+
71
+ ruby_forge = RubyForge.new
72
+ ruby_forge.login
73
+
74
+ %w( gem tgz zip ).each do |ext|
75
+ file = "pkg/#{PKG_FILE_NAME}.#{ext}"
76
+ puts "Releasing #{File.basename(file)}..."
77
+
78
+ ruby_forge.add_release(RUBY_FORGE_PROJECT, PKG_NAME, PKG_VERSION, file)
79
+ end
80
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'encrypted_strings'
@@ -0,0 +1,5 @@
1
+ require 'encrypted_strings/extensions/string'
2
+ require 'encrypted_strings/encryptor'
3
+ require 'encrypted_strings/symmetric_encryptor'
4
+ require 'encrypted_strings/asymmetric_encryptor'
5
+ require 'encrypted_strings/sha_encryptor'
@@ -0,0 +1,133 @@
1
+ require 'encrypted_strings/no_private_key_error'
2
+ require 'encrypted_strings/no_public_key_error'
3
+
4
+ module PluginAWeek #:nodoc:
5
+ module EncryptedStrings #:nodoc:
6
+ # Encryption in which the keys used to encrypt/decrypt come in pairs. Also known
7
+ # as public key encryption. Anything that's encrypted using the public key can
8
+ # only be decrypted with the same algorithm and a matching private key.
9
+ # Any message that is encrypted with the private key can only be decrypted
10
+ # with the matching public key.
11
+ #
12
+ # http://support.microsoft.com/kb/246071
13
+ class AsymmetricEncryptor < Encryptor
14
+ # The default private key to use during encryption. Default is nil.
15
+ @@default_private_key_file = nil
16
+ cattr_accessor :default_private_key_file
17
+
18
+ # The default public key to use during encryption. Default is nil.
19
+ @@default_public_key_file = nil
20
+ cattr_accessor :default_public_key_file
21
+
22
+ # The default algorithm to use. Default is nil.
23
+ @@default_algorithm = nil
24
+ cattr_accessor :default_algorithm
25
+
26
+ attr_reader :private_key_file
27
+ attr_reader :public_key_file
28
+ attr_accessor :algorithm
29
+ attr_accessor :key
30
+
31
+ # Configuration options:
32
+ # * <tt>private_key_file</tt> - Encrypted private key file
33
+ # * <tt>public_key_file</tt> - Public key file
34
+ # * <tt>key</tt> - The key to use in the symmetric encryptor
35
+ # * <tt>algorithm</tt> - Algorithm to use symmetrically encrypted strings
36
+ def initialize(options = {})
37
+ options = options.symbolize_keys
38
+ options.assert_valid_keys(
39
+ :private_key_file,
40
+ :public_key_file,
41
+ :key,
42
+ :algorithm
43
+ )
44
+ options.reverse_merge!(
45
+ :private_key_file => @@default_private_key_file,
46
+ :public_key_file => @@default_public_key_file,
47
+ :algorithm => @@default_algorithm
48
+ )
49
+
50
+ @public_key = @private_key = nil
51
+ @key = options[:key]
52
+ @algorithm = options[:algorithm]
53
+
54
+ self.private_key_file = options[:private_key_file]
55
+ self.public_key_file = options[:public_key_file]
56
+
57
+ super()
58
+ end
59
+
60
+ # Encrypts the given data
61
+ def encrypt(data)
62
+ raise NoPublicKeyError, "Public key file: #{@public_key_file}" unless public?
63
+
64
+ encrypted_data = public_rsa.public_encrypt(data)
65
+ Base64.encode64(encrypted_data)
66
+ end
67
+
68
+ # Decrypts the given data
69
+ def decrypt(data)
70
+ raise NoPrivateKeyError, "Private key file: #{@private_key_file}" unless private?
71
+
72
+ decrypted_data = Base64.decode64(data)
73
+ private_rsa.private_decrypt(decrypted_data)
74
+ end
75
+
76
+ # Sets the location of the private key and loads it
77
+ def private_key_file=(file)
78
+ @private_key_file = file and load_private_key
79
+ end
80
+
81
+ # Sets the location of the public key and loads it
82
+ def public_key_file=(file)
83
+ @public_key_file = file and load_public_key
84
+ end
85
+
86
+ # Is this string encrypted using a public key?
87
+ def public?
88
+ return true unless @public_key.nil?
89
+
90
+ load_public_key
91
+ !@public_key.nil?
92
+ end
93
+
94
+ # Is this string encrypted using a private key?
95
+ def private?
96
+ return true unless @private_key.nil?
97
+
98
+ load_private_key
99
+ !@private_key.nil?
100
+ end
101
+
102
+ private
103
+ def load_private_key #:nodoc:
104
+ @private_rsa = nil
105
+
106
+ if @private_key_file && File.file?(@private_key_file)
107
+ @private_key = File.open(@private_key_file) {|f| f.read}
108
+ end
109
+ end
110
+
111
+ def load_public_key #:nodoc:
112
+ @public_rsa = nil
113
+
114
+ if @public_key_file && File.file?(@public_key_file)
115
+ @public_key = File.open(@public_key_file) {|f| f.read}
116
+ end
117
+ end
118
+
119
+ # Retrieves private RSA from the encrypted private key
120
+ def private_rsa #:nodoc:
121
+ return @private_rsa ||= OpenSSL::PKey::RSA.new(@private_key) unless @key
122
+
123
+ private_key = SymmetricEncryptor.new(:key => @key, :algorithm => @algorithm).decrypt(@private_key)
124
+ OpenSSL::PKey::RSA.new(private_key)
125
+ end
126
+
127
+ # Retrieves the public RSA
128
+ def public_rsa #:nodoc:
129
+ @public_rsa ||= OpenSSL::PKey::RSA.new(@public_key)
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,17 @@
1
+ module PluginAWeek #:nodoc:
2
+ module EncryptedStrings #:nodoc:
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
+ # By default, decryption is not supported
12
+ def decrypt(data)
13
+ raise NotImplementedError, "Decryption is not supported using a(n) #{self.class.name}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,108 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+
4
+ module PluginAWeek #:nodoc:
5
+ module EncryptedStrings #:nodoc:
6
+ module Extensions #:nodoc:
7
+ # Adds encryption/decryption/equality methods
8
+ module String
9
+ def self.included(base) #:nodoc:
10
+ base.class_eval do
11
+ attr_accessor :encryptor
12
+
13
+ alias_method :equals_without_encryption, :==
14
+ alias_method :==, :equals_with_encryption
15
+ end
16
+ end
17
+
18
+ # Encrypts this string and replaces it with the encrypted value
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.
27
+ # The default encryption mode is sha.
28
+ #
29
+ # Configuration options are encryption-specified. See the encryptor
30
+ # class for that string to find out the options available.
31
+ def encrypt(*args)
32
+ encryptor = encryptor_from_args(*args)
33
+ encrypted_string = encryptor.encrypt(self)
34
+ encrypted_string.encryptor = encryptor
35
+
36
+ encrypted_string
37
+ end
38
+
39
+ # Is this string encrypted?
40
+ def encrypted?
41
+ !@encryptor.nil?
42
+ end
43
+
44
+ # Decrypts this string and replaces it with the decrypted value
45
+ def decrypt!(*args)
46
+ replace(decrypt(*args))
47
+ end
48
+
49
+ # Decrypts this string. If this is not a string that was previously encrypted,
50
+ # the encryption algorithm must be specified in the same way the
51
+ # algorithm is specified when encrypting a string.
52
+ def decrypt(*args)
53
+ raise ArgumentError, "An encrypt algorithm must be specified since we can't figure it out" if args.empty? && !@encryptor
54
+
55
+ encryptor = @encryptor || encryptor_from_args(*args)
56
+ encryptor.decrypt(self)
57
+ end
58
+
59
+ # Can this string be decrypted?
60
+ def can_decrypt?
61
+ !@encryptor.nil? && @encryptor.can_decrypt?
62
+ end
63
+
64
+ # Tests whether the other object is equal to this one. Encrypted strings
65
+ # will be tested not only on their encrypted strings, but also by
66
+ # decrypting them and running tests against the decrypted value
67
+ def equals_with_encryption(other)
68
+ if !(is_equal = equals_without_encryption(other)) && String === other
69
+ if encrypted?
70
+ if other.encrypted?
71
+ is_string_equal?(self, other) || is_string_equal?(other, self) || self.can_decrypt? && is_string_equal?(self.decrypt, other) || other.can_decrypt? && is_string_equal?(other.decrypt, self)
72
+ else
73
+ is_string_equal?(other, self)
74
+ end
75
+ else
76
+ if other.encrypted?
77
+ is_string_equal?(self, other)
78
+ else
79
+ false
80
+ end
81
+ end
82
+ else
83
+ is_equal
84
+ end
85
+ end
86
+
87
+ private
88
+ def is_string_equal?(value, encrypted_value) #:nodoc:
89
+ if encrypted_value.can_decrypt?
90
+ encrypted_value.decrypt.equals_without_encryption(value)
91
+ else
92
+ encrypted_value.equals_without_encryption(encrypted_value.encryptor.encrypt(value))
93
+ end
94
+ end
95
+
96
+ def encryptor_from_args(*args) #:nodoc:
97
+ options = args.last.is_a?(::Hash) ? args.pop : {}
98
+ mode = (args.first || :sha).to_sym
99
+ "PluginAWeek::EncryptedStrings::#{mode.to_s.classify}Encryptor".constantize.new(options)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ ::String.class_eval do
107
+ include PluginAWeek::EncryptedStrings::Extensions::String
108
+ end
@@ -0,0 +1,7 @@
1
+ module PluginAWeek #:nodoc:
2
+ module EncryptedStrings #:nodoc:
3
+ # Indicates no key was specified
4
+ class NoKeyError < StandardError
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module PluginAWeek #:nodoc:
2
+ module EncryptedStrings #:nodoc:
3
+ # Indicates no private key was found
4
+ class NoPrivateKeyError < StandardError
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module PluginAWeek #:nodoc:
2
+ module EncryptedStrings #:nodoc:
3
+ # Indicates no public key was found
4
+ class NoPublicKeyError < StandardError
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,35 @@
1
+ require 'digest/sha1'
2
+
3
+ module PluginAWeek #:nodoc:
4
+ module EncryptedStrings #:nodoc:
5
+ # Encrypts a string using a Secure Hash Algorithm (SHA), specifically SHA-1.
6
+ class ShaEncryptor < Encryptor
7
+ # The default salt value to use during encryption
8
+ @@default_salt = 'salt'
9
+ cattr_accessor :default_salt
10
+
11
+ attr_accessor :salt
12
+
13
+ # Configuration options:
14
+ # * <tt>salt</tt> - Salt value to use for encryption
15
+ def initialize(options = {})
16
+ options = options.symbolize_keys
17
+ options.assert_valid_keys(:salt)
18
+ options.reverse_merge!(:salt => @@default_salt)
19
+ @salt = options[:salt]
20
+
21
+ super()
22
+ end
23
+
24
+ # Decryption is not supported.
25
+ def can_decrypt?
26
+ false
27
+ end
28
+
29
+ # Returns the encrypted value of the data
30
+ def encrypt(data)
31
+ Digest::SHA1.hexdigest(data + @salt)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,64 @@
1
+ require 'encrypted_strings/no_key_error'
2
+
3
+ module PluginAWeek #:nodoc:
4
+ module EncryptedStrings #:nodoc
5
+ # Symmetric encryption uses a key and a specific algorithm to encrypt the
6
+ # string. As long as the key and algorithm are known, the string can be
7
+ # decrypted.
8
+ #
9
+ # http://support.microsoft.com/kb/246071
10
+ class SymmetricEncryptor < Encryptor
11
+ # The default algorithm to use for encryption. Default is DES
12
+ @@default_algorithm = 'DES-EDE3-CBC'
13
+ cattr_accessor :default_algorithm
14
+
15
+ # The default key to use. Default is nil
16
+ @@default_key = nil
17
+ cattr_accessor :default_key
18
+
19
+ attr_accessor :algorithm
20
+ attr_accessor :key
21
+
22
+ # Configuration options:
23
+ # * <tt>key</tt> - Private key
24
+ # * <tt>algorithm</tt> - Algorithm to use
25
+ def initialize(options = {})
26
+ options = options.symbolize_keys
27
+ options.assert_valid_keys(
28
+ :key,
29
+ :algorithm
30
+ )
31
+ options.reverse_merge!(:key => @@default_key)
32
+ options[:algorithm] ||= @@default_algorithm # Saves us from nil values for algorithm
33
+
34
+ @key = options[:key]
35
+ raise NoKeyError if @key.nil?
36
+
37
+ @algorithm = options[:algorithm]
38
+
39
+ super()
40
+ end
41
+
42
+ # Decrypts the current string using the current key and algorithm specified
43
+ def decrypt(data)
44
+ cipher.decrypt(@key)
45
+ decrypted_data = cipher.update(Base64.decode64(data))
46
+ decrypted_data << cipher.final
47
+ end
48
+
49
+ # Encrypts the current string using the current key and algorithm specified
50
+ def encrypt(data)
51
+ cipher.encrypt(@key)
52
+ encrypted_data = cipher.update(data)
53
+ encrypted_data << cipher.final
54
+
55
+ Base64.encode64(encrypted_data)
56
+ end
57
+
58
+ private
59
+ def cipher #:nodoc:
60
+ @cipher ||= OpenSSL::Cipher::Cipher.new(@algorithm)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,97 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class AsymmetricEncryptorTest < Test::Unit::TestCase
4
+ def setup
5
+ @data = 'encrypted_strings'
6
+ @key = 'secret'
7
+ @public_key_file = File.dirname(__FILE__) + '/keys/public'
8
+ @private_key_file = File.dirname(__FILE__) + '/keys/private'
9
+ @encrypted_public_key_file = File.dirname(__FILE__) + '/keys/encrypted_public'
10
+ @encrypted_private_key_file = File.dirname(__FILE__) + '/keys/encrypted_private'
11
+
12
+ @encrypted_data = "NMGkkSu8dFdM455ru46b8TIkWQDHVdi4aJFZBCZ5p2VQV88OJnLBnnWYBXZk\n8HcyXzKb1I9lxuVHU/eZorGl7Q==\n"
13
+ @encrypted_data_with_encrypted_keys = "C6sJrSzSaVZ9gCPanUpUmSir5At6tMfBzPvJO/MXYJVJNxF3uKMy9IsJHqos\nz5tVAdyOUNBr3jroqFK22mdKqw==\n"
14
+
15
+ PluginAWeek::EncryptedStrings::AsymmetricEncryptor.default_public_key_file = nil
16
+ PluginAWeek::EncryptedStrings::AsymmetricEncryptor.default_private_key_file = nil
17
+ end
18
+
19
+ def test_should_not_be_public_without_public_key_file
20
+ encryptor = PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new
21
+ assert !encryptor.public?
22
+ end
23
+
24
+ def test_should_not_be_private_without_privae_key_file
25
+ encryptor = PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new
26
+ assert !encryptor.private?
27
+ end
28
+
29
+ def test_should_read_key_files
30
+ encryptor = PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new(
31
+ :public_key_file => @public_key_file,
32
+ :private_key_file => @private_key_file
33
+ )
34
+ assert encryptor.public?
35
+ assert encryptor.private?
36
+ end
37
+ #
38
+ def test_should_read_encrypted_key_files
39
+ encryptor = PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new(
40
+ :public_key_file => @encrypted_public_key_file,
41
+ :private_key_file => @encrypted_private_key_file
42
+ )
43
+ assert encryptor.public?
44
+ assert encryptor.private?
45
+ end
46
+ #
47
+ def test_should_decrypt_files
48
+ encryptor = PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new(
49
+ :public_key_file => @public_key_file,
50
+ :private_key_file => @private_key_file
51
+ )
52
+
53
+ assert_equal @data, encryptor.decrypt(@encrypted_data)
54
+ end
55
+ #
56
+ def test_should_decrypt_files_with_encrypted_key
57
+ encryptor = PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new(
58
+ :public_key_file => @encrypted_public_key_file,
59
+ :private_key_file => @encrypted_private_key_file,
60
+ :key => @key
61
+ )
62
+
63
+ assert_equal @data, encryptor.decrypt(@encrypted_data_with_encrypted_keys)
64
+ end
65
+ #
66
+ def test_should_decrypt_files_with_default_key
67
+ set_default_key_files @public_key_file, @private_key_file
68
+ assert_equal @data, PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new.decrypt(@encrypted_data)
69
+ end
70
+
71
+ def test_should_decrypt_files_with_default_encrypted_key
72
+ set_default_key_files @encrypted_public_key_file, @encrypted_private_key_file
73
+ assert_equal @data, PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new(:key => @key).decrypt(@encrypted_data_with_encrypted_keys)
74
+ end
75
+
76
+ def test_should_read_key_files_with_default_key
77
+ set_default_key_files @public_key_file, @private_key_file
78
+
79
+ encryptor = PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new
80
+ assert encryptor.private?
81
+ assert encryptor.public?
82
+ end
83
+
84
+ def test_should_read_encrypted_key_files_with_default_key
85
+ set_default_key_files @encrypted_public_key_file, @encrypted_private_key_file
86
+
87
+ encryptor = PluginAWeek::EncryptedStrings::AsymmetricEncryptor.new
88
+ assert encryptor.private?
89
+ assert encryptor.public?
90
+ end
91
+
92
+ private
93
+ def set_default_key_files(public_key, private_key)
94
+ PluginAWeek::EncryptedStrings::AsymmetricEncryptor.default_public_key_file = public_key
95
+ PluginAWeek::EncryptedStrings::AsymmetricEncryptor.default_private_key_file = private_key
96
+ end
97
+ end
@@ -0,0 +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
15
+ end
@@ -0,0 +1,12 @@
1
+ OBNa1q8kbx8pyZZjIpr/pZV0oulE2czh5JlPW/13XsBvoz+A2zxA9gchhi6c
2
+ 3yvfqgcZdojcsep+IiTqeg3gOPB2xNbedpP1lm+9tEfgdb9r1CLzRcURh7Hg
3
+ ufWgyEkS0lloz/YLy4hg9YDKetFNF9fnrk3xVwZPwFVuk4l/Unw1FTXLHsrq
4
+ KG27cR8mvNOow4bk4LVhk/avFSM85m3ITySEnyJsQQDzsI/RrWcQ7Js+8Ynv
5
+ esN51E/T0CYtkMEne2zSaD5qUTJlQ7Qtn4UUeZkpYjn4xQZPxw4OjL6zofg7
6
+ lsqElSv1/qP3QI8aKcQQklVsHRc5AgsxOFX4J6g6lo4kOGOwn0Ex8IRDfOej
7
+ pq4SUDh9IXz+6FBieQrObB/xEsKysVwRSzXre6ObHlPFsigg5ekFPyCv5ZTz
8
+ 0iP8+xe/FJRrYdR3r3F5pRkOy0pw9EqlrLjmOx3/fgxhLq8FWmcSBbH3h3SG
9
+ GkJlfHNjF77FTJjnHKzRS+5VpdW4IHbsjL+NlI1z9Ol//czYvSGv85NdJvkq
10
+ PmH3o0+uYdwY5PeSMOPV21nJ3dwiKlm5IMFasL3C5yVJNVTVZTS7vWdcgZ4U
11
+ XfWQ9Y266ibbqXPluv4nxt1+kgjxmPbjPdYrlB5t7a2+unzT3oE3f4VGOG+k
12
+ YqFg0ErHN+fu
@@ -0,0 +1,4 @@
1
+ -----BEGIN RSA PUBLIC KEY-----
2
+ MEgCQQCvktJgveIcgTH98hAhMjo0g6/GVMJaYdUh+/zQn4RBWASRmwEfJqggsfKT
3
+ pSNendZQMD8kKS8J1YTBr60ToM25AgMBAAE=
4
+ -----END RSA PUBLIC KEY-----
data/test/keys/private ADDED
@@ -0,0 +1,9 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIBOwIBAAJBAL/xeY6aqFx6z1ThNOwgPgxv3tsonTlCj8VkN3Ikumg6SzBuLxlV
3
+ i9gFQZ7K9Pv9o/7+xUTYODqBpVhwgLBeu2cCAwEAAQJAHyjFMfg7Yp/xLndMzxRA
4
+ 3mX+yJckRtpeWo31TktWE3syks1r9OrfmxKiStM9kFRubeBHTihZrW92TYkROLxh
5
+ uQIhAPuftVTJZFDNxeYDKIMIMqwR8KZgtuf25cv4pTxYwPqLAiEAw0gNwDJHBkvo
6
+ da4402pZNQmBA6qCSf0svDXqoEoaShUCIGBma340Oe6LJ0pb42Vv+pnZtazIWMq9
7
+ 2IQwmn1oM2bJAiEAhgP869mVRIzzi091UCG79tn+4DU0FPLasI+P5VD1mcECIQDb
8
+ 3ndvbPcElVvdJgabxyWJJsNtBBNZYPsuc6NrQyShOw==
9
+ -----END RSA PRIVATE KEY-----
data/test/keys/public ADDED
@@ -0,0 +1,4 @@
1
+ -----BEGIN RSA PUBLIC KEY-----
2
+ MEgCQQC/8XmOmqhces9U4TTsID4Mb97bKJ05Qo/FZDdyJLpoOkswbi8ZVYvYBUGe
3
+ yvT7/aP+/sVE2Dg6gaVYcICwXrtnAgMBAAE=
4
+ -----END RSA PUBLIC KEY-----
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class NoKeyErrorTest < Test::Unit::TestCase
4
+ def test_should_exist
5
+ assert_not_nil PluginAWeek::EncryptedStrings::NoKeyError
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class NoPrivateKeyErrorTest < Test::Unit::TestCase
4
+ def test_should_exist
5
+ assert_not_nil PluginAWeek::EncryptedStrings::NoPrivateKeyError
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class NoPublicKeyErrorTest < Test::Unit::TestCase
4
+ def test_should_exist
5
+ assert_not_nil PluginAWeek::EncryptedStrings::NoPublicKeyError
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class ShaEncryptorTest < Test::Unit::TestCase
4
+ def setup
5
+ PluginAWeek::EncryptedStrings::ShaEncryptor.default_salt = 'salt'
6
+ end
7
+
8
+ def test_should_encrypt_with_default_salt_if_salt_not_specified
9
+ assert_equal 'f438229716cab43569496f3a3630b3727524b81b', PluginAWeek::EncryptedStrings::ShaEncryptor.new.encrypt('test')
10
+ end
11
+
12
+ def test_should_encrypt_with_custom_salt_if_salt_specified
13
+ assert_equal '18e3256d71529db8fa65b2eef24a69ddad7070f3', PluginAWeek::EncryptedStrings::ShaEncryptor.new(:salt => 'different salt').encrypt('test')
14
+ end
15
+
16
+ def test_should_not_be_able_to_decrypt
17
+ assert !PluginAWeek::EncryptedStrings::ShaEncryptor.new.can_decrypt?
18
+ end
19
+
20
+ def test_should_raise_exception_if_trying_to_decrypt
21
+ assert_raises(NotImplementedError) { PluginAWeek::EncryptedStrings::ShaEncryptor.new.decrypt('test') }
22
+ end
23
+ end
@@ -0,0 +1,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
+
7
+ encrypted_string = 'test'.encrypt(:salt => 'different_salt')
8
+ assert_instance_of PluginAWeek::EncryptedStrings::ShaEncryptor, encrypted_string.encryptor
9
+ assert_equal 'different_salt', encrypted_string.encryptor.salt
10
+ end
11
+
12
+ def test_should_use_custom_encryptor_if_mode_specified
13
+ encrypted_string = 'test'.encrypt(:symmetric, :key => 'key')
14
+ assert_instance_of PluginAWeek::EncryptedStrings::SymmetricEncryptor, encrypted_string.encryptor
15
+ end
16
+
17
+ def test_should_replace_string_with_bang_encryption
18
+ encrypted_string = 'test'
19
+ encrypted_string.encrypt!
20
+
21
+ assert !'test'.equals_without_encryption(encrypted_string)
22
+ assert_instance_of PluginAWeek::EncryptedStrings::ShaEncryptor, encrypted_string.encryptor
23
+ end
24
+
25
+ def test_should_use_encryptor_for_decryption_by_default
26
+ encrypted_string = 'test'.encrypt(:symmetric, :key => 'secret')
27
+ assert 'test'.equals_without_encryption(encrypted_string.decrypt)
28
+ end
29
+
30
+ def test_should_allow_custom_mode_when_decrypting
31
+ assert_equal 'test', "MU6e/5LvhKA=\n".decrypt(:symmetric, :key => 'secret')
32
+ end
33
+
34
+ def test_should_replace_string_with_bang_decryption
35
+ encrypted_string = "MU6e/5LvhKA=\n"
36
+ encrypted_string.decrypt!(:symmetric, :key => 'secret')
37
+
38
+ assert !"MU6e/5LvhKA=\n".equals_without_encryption(encrypted_string)
39
+ assert 'test'.equals_without_encryption(encrypted_string)
40
+ end
41
+
42
+ def test_should_be_able_to_check_equality_without_decryption_support
43
+ value = 'test'
44
+ encrypted_string = 'test'.encrypt(:sha)
45
+ encrypted_encrypted_string = encrypted_string.encrypt(:sha)
46
+
47
+ assert_equal value, encrypted_string
48
+ assert_equal encrypted_string, value
49
+ assert_equal encrypted_string, encrypted_encrypted_string
50
+ assert_equal encrypted_encrypted_string, encrypted_string
51
+ assert_equal encrypted_string.to_s, encrypted_string
52
+ assert_equal encrypted_string, encrypted_string.to_s
53
+ assert_equal encrypted_string, encrypted_string
54
+
55
+ assert_not_equal value, encrypted_encrypted_string
56
+ assert_not_equal encrypted_encrypted_string, value
57
+ end
58
+
59
+ def test_should_be_able_to_check_equality_with_decryption_support
60
+ PluginAWeek::EncryptedStrings::SymmetricEncryptor.default_key = 'secret'
61
+
62
+ value = 'test'
63
+ encrypted_string = value.encrypt(:symmetric)
64
+ encrypted_encrypted_string = encrypted_string.encrypt(:symmetric)
65
+
66
+ assert_equal value, encrypted_string
67
+ assert_equal encrypted_string, value
68
+ assert_equal encrypted_string, encrypted_encrypted_string
69
+ assert_equal encrypted_encrypted_string, encrypted_string
70
+ assert_equal encrypted_string.to_s, encrypted_string
71
+ assert_equal encrypted_string, encrypted_string.to_s
72
+ assert_equal encrypted_string, encrypted_string
73
+
74
+ assert_not_equal value, encrypted_encrypted_string
75
+ assert_not_equal encrypted_encrypted_string, value
76
+ end
77
+ end
@@ -0,0 +1,36 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class SymmetricallyEncryptedStringTest < Test::Unit::TestCase
4
+ def setup
5
+ @data = 'test'
6
+ @key = 'secret'
7
+ @encrypted = "MU6e/5LvhKA=\n"
8
+ PluginAWeek::EncryptedStrings::SymmetricEncryptor.default_key = nil
9
+ end
10
+
11
+ def test_should_raise_exception_if_no_key_specified
12
+ assert_raises(PluginAWeek::EncryptedStrings::NoKeyError) { PluginAWeek::EncryptedStrings::SymmetricEncryptor.new }
13
+ end
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
+ def test_encrypt_with_default_key_if_key_not_specified
20
+ PluginAWeek::EncryptedStrings::SymmetricEncryptor.default_key = @key
21
+ assert_equal @encrypted, PluginAWeek::EncryptedStrings::SymmetricEncryptor.new.encrypt(@data)
22
+ end
23
+
24
+ def test_should_be_able_to_decrypt
25
+ assert PluginAWeek::EncryptedStrings::SymmetricEncryptor.new(:key => @key).can_decrypt?
26
+ end
27
+
28
+ def test_should_decrypt_encrypted_string_with_custom_key_if_key_specified
29
+ assert_equal @data, PluginAWeek::EncryptedStrings::SymmetricEncryptor.new(:key => @key).decrypt(@encrypted)
30
+ end
31
+
32
+ def test_should_decrypt_encrypted_string_with_default_key_if_key_not_specified
33
+ PluginAWeek::EncryptedStrings::SymmetricEncryptor.default_key = @key
34
+ assert_equal @data, PluginAWeek::EncryptedStrings::SymmetricEncryptor.new.decrypt(@encrypted)
35
+ end
36
+ end
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+
3
+ require 'rubygems'
4
+ require 'test/unit'
5
+ require 'active_support'
6
+ require "#{File.dirname(__FILE__)}/../init"
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: encrypted_strings
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-08-05 00:00:00 -04:00
8
+ summary: Dead-simple string encryption/decryption syntax.
9
+ require_paths:
10
+ - lib
11
+ email: info@pluginaweek.org
12
+ homepage: http://www.pluginaweek.org
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: encrypted_strings
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Aaron Pfeifer, Neil Abraham
31
+ files:
32
+ - lib/encrypted_strings
33
+ - lib/encrypted_strings/asymmetric_encryptor.rb
34
+ - lib/encrypted_strings/encryptor.rb
35
+ - lib/encrypted_strings/extensions
36
+ - lib/encrypted_strings/extensions/string.rb
37
+ - lib/encrypted_strings/no_key_error.rb
38
+ - lib/encrypted_strings/no_private_key_error.rb
39
+ - lib/encrypted_strings/no_public_key_error.rb
40
+ - lib/encrypted_strings/sha_encryptor.rb
41
+ - lib/encrypted_strings/symmetric_encryptor.rb
42
+ - lib/encrypted_strings.rb
43
+ - test/asymmetric_encryptor_test.rb
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
51
+ - test/no_private_key_error_test.rb
52
+ - test/no_public_key_error_test.rb
53
+ - test/sha_encryptor_test.rb
54
+ - test/string_test.rb
55
+ - test/symmetric_encryptor_test.rb
56
+ - test/test_helper.rb
57
+ - init.rb
58
+ - MIT-LICENSE
59
+ - Rakefile
60
+ - README
61
+ test_files:
62
+ - test/asymmetric_encryptor_test.rb
63
+ - test/encryptor_test.rb
64
+ - test/no_key_error_test.rb
65
+ - test/no_private_key_error_test.rb
66
+ - test/no_public_key_error_test.rb
67
+ - test/sha_encryptor_test.rb
68
+ - test/string_test.rb
69
+ - test/symmetric_encryptor_test.rb
70
+ rdoc_options: []
71
+
72
+ extra_rdoc_files: []
73
+
74
+ executables: []
75
+
76
+ extensions: []
77
+
78
+ requirements: []
79
+
80
+ dependencies:
81
+ - !ruby/object:Gem::Dependency
82
+ name: activesupport
83
+ version_requirement:
84
+ version_requirements: !ruby/object:Gem::Version::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 1.3.1
89
+ version: