encrypted_strings 0.0.1
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/MIT-LICENSE +20 -0
- data/README +97 -0
- data/Rakefile +80 -0
- data/init.rb +1 -0
- data/lib/encrypted_strings.rb +5 -0
- data/lib/encrypted_strings/asymmetric_encryptor.rb +133 -0
- data/lib/encrypted_strings/encryptor.rb +17 -0
- data/lib/encrypted_strings/extensions/string.rb +108 -0
- data/lib/encrypted_strings/no_key_error.rb +7 -0
- data/lib/encrypted_strings/no_private_key_error.rb +7 -0
- data/lib/encrypted_strings/no_public_key_error.rb +7 -0
- data/lib/encrypted_strings/sha_encryptor.rb +35 -0
- data/lib/encrypted_strings/symmetric_encryptor.rb +64 -0
- data/test/asymmetric_encryptor_test.rb +97 -0
- data/test/encryptor_test.rb +15 -0
- data/test/keys/encrypted_private +12 -0
- data/test/keys/encrypted_public +4 -0
- data/test/keys/private +9 -0
- data/test/keys/public +4 -0
- data/test/no_key_error_test.rb +7 -0
- data/test/no_private_key_error_test.rb +7 -0
- data/test/no_public_key_error_test.rb +7 -0
- data/test/sha_encryptor_test.rb +23 -0
- data/test/string_test.rb +77 -0
- data/test/symmetric_encryptor_test.rb +36 -0
- data/test/test_helper.rb +6 -0
- metadata +89 -0
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,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,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
|
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,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
|
data/test/string_test.rb
ADDED
@@ -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
|
data/test/test_helper.rb
ADDED
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:
|