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 +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:
|