ssoper-acts_as_encryptable 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Changelog +12 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +61 -0
- data/Rakefile +36 -0
- data/acts_as_encryptable.gemspec +36 -0
- data/generators/acts_as_encryptable_migration/acts_as_encryptable_migration_generator.rb +25 -0
- data/lib/acts_as_encryptable.rb +2 -0
- data/lib/acts_as_encryptable/base.rb +90 -0
- data/lib/acts_as_encryptable/crypto.rb +46 -0
- data/sample_keys/rsa_key +15 -0
- data/sample_keys/rsa_key.pub +5 -0
- data/test/test_helper.rb +22 -0
- data/test/unit/base_test.rb +69 -0
- data/test/unit/crypto_test.rb +24 -0
- metadata +81 -0
data/Changelog
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
== 3-26-2009
|
2
|
+
|
3
|
+
* Changed how encrypted data is saved, now put on separate column in the same table as encrypted model
|
4
|
+
* Added tests
|
5
|
+
* Can configure name of encrypted column
|
6
|
+
* Added documentation
|
7
|
+
* Log warning if default sample keys are being used while in production mode
|
8
|
+
|
9
|
+
|
10
|
+
== 3-25-2009
|
11
|
+
|
12
|
+
* Initial build
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Sean Soper
|
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.rdoc
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
= Acts As Encryptable
|
2
|
+
|
3
|
+
Encrypt and decrypt your data using asymmetric keys
|
4
|
+
|
5
|
+
|
6
|
+
== Installation
|
7
|
+
|
8
|
+
Run this if the gem isn't installed already
|
9
|
+
gem install ssoper-acts_as_encryptable --source=http://gems.github.com
|
10
|
+
|
11
|
+
Or place in your environment.rb
|
12
|
+
config.gem 'ssoper-acts_as_encryptable', :source => 'http://gems.github.com'
|
13
|
+
|
14
|
+
|
15
|
+
== Configuration
|
16
|
+
|
17
|
+
After installing be sure to add a column to any tables that need to be encrypted
|
18
|
+
class AddEncryptionFieldsToCreditCards < ActiveRecord::Migration
|
19
|
+
def self.up
|
20
|
+
add_column :credit_cards, :encrypted, :text
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.down
|
24
|
+
remove_column :credit_cards, :encrypted
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
Or you can use the migration helper to generate the migration for the model
|
29
|
+
./script/generate acts_as_encryptable_migration credit_cards
|
30
|
+
|
31
|
+
And in your model
|
32
|
+
class CreditCard < ActiveRecord::Base
|
33
|
+
attr_accessor :first_name, :last_name, :number
|
34
|
+
acts_as_encryptable :first_name, :last_name, :number
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
== Usage
|
39
|
+
|
40
|
+
Encrypt your data
|
41
|
+
card = CreditCard.new
|
42
|
+
card.first_name = 'Test'
|
43
|
+
card.last_name = 'User'
|
44
|
+
card.number = '1234567890'
|
45
|
+
card.save
|
46
|
+
|
47
|
+
Decrypt your data
|
48
|
+
card = CreditCard.last
|
49
|
+
card.decrypt!
|
50
|
+
=> { :first_name => 'Test', :last_name => 'User', :number => '1234567890' }
|
51
|
+
|
52
|
+
|
53
|
+
== Tests
|
54
|
+
|
55
|
+
> rake test
|
56
|
+
|
57
|
+
|
58
|
+
== Acknowledgements
|
59
|
+
|
60
|
+
* Tobias Lütke for his blog post on asymmetric encryption using Ruby's native SSL libraries
|
61
|
+
* Paul Barry for helping simplify the functionality
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
namespace :gem do
|
5
|
+
|
6
|
+
task :default => :build
|
7
|
+
|
8
|
+
desc 'Build the acts_as_encryptable gem'
|
9
|
+
task :build do
|
10
|
+
Dir['*.gem'].each do |gem_filename|
|
11
|
+
sh "rm -rf #{gem_filename}"
|
12
|
+
end
|
13
|
+
sh "gem build acts_as_encryptable.gemspec"
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Install the acts_as_encryptable gem'
|
17
|
+
task :install do
|
18
|
+
gem_filename = Dir['*.gem'].first
|
19
|
+
sh "sudo gem install --local #{gem_filename}"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
task :default => ['gem:build', 'gem:install']
|
25
|
+
|
26
|
+
namespace :test do
|
27
|
+
Rake::TestTask.new(:unit) do |t|
|
28
|
+
t.libs << 'test'
|
29
|
+
t.pattern = 'test/unit/*_test.rb'
|
30
|
+
t.verbose = true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
task :test do
|
35
|
+
Rake::Task['test:unit'].invoke
|
36
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "acts_as_encryptable"
|
3
|
+
s.version = "1.0.4"
|
4
|
+
s.date = "2009-03-27"
|
5
|
+
s.author = "Sean Soper"
|
6
|
+
s.email = "sean.soper@gmail.com"
|
7
|
+
s.summary = "Encrypt and decrypt your data using asymmetric keys"
|
8
|
+
s.description = "Allow your models to encrypt an arbitrary amount of data using asymmetric keys"
|
9
|
+
s.homepage = "http://github.com/ssoper/acts_as_encryptable"
|
10
|
+
s.require_path = "lib"
|
11
|
+
s.files = %w{ acts_as_encryptable.gemspec
|
12
|
+
lib/acts_as_encryptable.rb
|
13
|
+
lib/acts_as_encryptable/base.rb
|
14
|
+
lib/acts_as_encryptable/crypto.rb
|
15
|
+
generators/acts_as_encryptable_migration/acts_as_encryptable_migration_generator.rb
|
16
|
+
sample_keys/rsa_key.pub
|
17
|
+
sample_keys/rsa_key
|
18
|
+
test/test_helper.rb
|
19
|
+
test/unit/base_test.rb
|
20
|
+
test/unit/crypto_test.rb
|
21
|
+
MIT-LICENSE
|
22
|
+
Rakefile
|
23
|
+
README.rdoc
|
24
|
+
Changelog }
|
25
|
+
s.has_rdoc = true
|
26
|
+
s.extra_rdoc_files = %w{ MIT-LICENSE
|
27
|
+
README.rdoc }
|
28
|
+
s.rdoc_options = ["--line-numbers",
|
29
|
+
"--inline-source",
|
30
|
+
"--title",
|
31
|
+
"acts_as_encryptable",
|
32
|
+
"--main",
|
33
|
+
"README.rdoc"]
|
34
|
+
s.rubygems_version = "1.3.1"
|
35
|
+
s.add_dependency "capistrano", ">= 2.5.0"
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class ActsAsEncryptableMigrationGenerator < Rails::Generator::NamedBase
|
2
|
+
def manifest
|
3
|
+
record do |m|
|
4
|
+
m.migration_template 'migration:migration.rb', 'db/migrate', {
|
5
|
+
:assigns => migration_local_assigns,
|
6
|
+
:migration_file_name => "add_encryption_field_to_#{model_name}"
|
7
|
+
}
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def model_name
|
14
|
+
return ARGV.first
|
15
|
+
end
|
16
|
+
|
17
|
+
def migration_local_assigns
|
18
|
+
returning(assigns = {}) do
|
19
|
+
assigns[:migration_action] = "add"
|
20
|
+
assigns[:class_name] = "add_encryption_field_to_#{model_name}"
|
21
|
+
assigns[:table_name] = model_name
|
22
|
+
assigns[:attributes] = [Rails::Generator::GeneratedAttribute.new("encrypted", "text")]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module ActsAsEncryptable
|
2
|
+
module Base
|
3
|
+
WARNING_MSG = "\n \e[0m\e[1;36m[\e[37mActsAsEncryptable\e[36m] \e[1;31mUsing the provided sample keys in production mode is highly discouraged. Generate your own RSA keys using the provided crypto libraries.\e[0m\n\n"
|
4
|
+
MAX_CHUNK_SIZE = 118
|
5
|
+
ENCRYPTED_CHUNK_SIZE = 175
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def acts_as_encryptable(*args)
|
13
|
+
self.class_eval do
|
14
|
+
has_many :encrypted_chunks, :as => :encryptable
|
15
|
+
before_save :encrypt!
|
16
|
+
|
17
|
+
sample_key_public = File.join(File.dirname(__FILE__), '/../../sample_keys/rsa_key.pub')
|
18
|
+
sample_key_private = File.join(File.dirname(__FILE__), '/../../sample_keys/rsa_key')
|
19
|
+
|
20
|
+
options = {
|
21
|
+
:public_key => sample_key_public,
|
22
|
+
:private_key => sample_key_private,
|
23
|
+
:column => :encrypted
|
24
|
+
}
|
25
|
+
options.merge!(args.pop) if args.last.is_a? Hash
|
26
|
+
|
27
|
+
if (sample_key_public == options[:public_key]) and
|
28
|
+
(ENV['RAILS_ENV'] && ENV['RAILS_ENV'] == 'production')
|
29
|
+
RAILS_DEFAULT_LOGGER.warn WARNING_MSG
|
30
|
+
end
|
31
|
+
|
32
|
+
write_inheritable_attribute(:encrypted_fields, args.uniq)
|
33
|
+
class_inheritable_reader :encrypted_fields
|
34
|
+
|
35
|
+
write_inheritable_attribute(:public_key, ActsAsEncryptable::Crypto::Key.from_file(options[:public_key]))
|
36
|
+
class_inheritable_reader :public_key
|
37
|
+
|
38
|
+
write_inheritable_attribute(:private_key, ActsAsEncryptable::Crypto::Key.from_file(options[:private_key]))
|
39
|
+
class_inheritable_reader :private_key
|
40
|
+
|
41
|
+
write_inheritable_attribute(:encrypted_column, options[:column])
|
42
|
+
class_inheritable_reader :encrypted_column
|
43
|
+
|
44
|
+
include ActsAsEncryptable::Base::InstanceMethods
|
45
|
+
extend ActsAsEncryptable::Base::SingletonMethods
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module SingletonMethods
|
51
|
+
def chunkize(str, chunk_size)
|
52
|
+
(0..((str.length/chunk_size.to_f).ceil - 1)).each do |x|
|
53
|
+
start, stop = x * chunk_size, (x + 1) * chunk_size
|
54
|
+
start += 1 if start > 0
|
55
|
+
yield str[start..stop]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module InstanceMethods
|
61
|
+
def encrypt!
|
62
|
+
yaml_data = self.class.encrypted_fields.inject({}) do |result, field|
|
63
|
+
result.merge!(field => instance_variable_get("@#{field}".to_sym))
|
64
|
+
end.to_yaml
|
65
|
+
|
66
|
+
chunks = ''
|
67
|
+
self.class.chunkize(yaml_data, MAX_CHUNK_SIZE) do |chunk|
|
68
|
+
chunks << self.class.public_key.encrypt(chunk)
|
69
|
+
end
|
70
|
+
|
71
|
+
self.send("#{self.class.encrypted_column}=", chunks)
|
72
|
+
end
|
73
|
+
|
74
|
+
def decrypt!
|
75
|
+
encrypted_data = self.send("#{self.class.encrypted_column}")
|
76
|
+
|
77
|
+
chunks = ''
|
78
|
+
self.class.chunkize(encrypted_data, ENCRYPTED_CHUNK_SIZE) do |chunk|
|
79
|
+
chunks << self.class.private_key.decrypt(chunk)
|
80
|
+
end
|
81
|
+
|
82
|
+
YAML::load(chunks).each do |k, v|
|
83
|
+
instance_variable_set("@#{k}".to_sym, v)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
ActiveRecord::Base.send(:include, ActsAsEncryptable::Base)
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
module ActsAsEncryptable
|
4
|
+
|
5
|
+
# Originally posted by Tobias Lütke
|
6
|
+
# http://blog.leetsoft.com/2006/03/14/simple-encryption
|
7
|
+
module Crypto
|
8
|
+
def self.create_keys(priv = "rsa_key", pub = "#{priv}.pub", bits = 1024)
|
9
|
+
private_key = OpenSSL::PKey::RSA.new(bits)
|
10
|
+
File.open(priv, "w+") { |fp| fp << private_key.to_s }
|
11
|
+
File.open(pub, "w+") { |fp| fp << private_key.public_key.to_s }
|
12
|
+
private_key
|
13
|
+
end
|
14
|
+
|
15
|
+
class Key
|
16
|
+
def initialize(data)
|
17
|
+
@public = (data =~ /^-----BEGIN (RSA|DSA) PRIVATE KEY-----$/).nil?
|
18
|
+
@key = OpenSSL::PKey::RSA.new(data)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.from_file(filename)
|
22
|
+
self.new File.read( filename )
|
23
|
+
end
|
24
|
+
|
25
|
+
def encrypt(text)
|
26
|
+
Base64.encode64(@key.send("#{key_type}_encrypt", text))
|
27
|
+
end
|
28
|
+
|
29
|
+
def decrypt(text)
|
30
|
+
@key.send("#{key_type}_decrypt", Base64.decode64(text))
|
31
|
+
end
|
32
|
+
|
33
|
+
def private?
|
34
|
+
!@public
|
35
|
+
end
|
36
|
+
|
37
|
+
def public?
|
38
|
+
@public
|
39
|
+
end
|
40
|
+
|
41
|
+
def key_type
|
42
|
+
@public ? :public : :private
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/sample_keys/rsa_key
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIICWwIBAAKBgQDN2qBMNriTzfnGTcPkkPWR/Ep6jAcOBGjmFj15hPzshjgk++dr
|
3
|
+
Z74AVlE/3EsCZ1mY16T1UDz8c8izVr8AhDaixhZBrRkx4xzipjHZ98JJwQhVQQIA
|
4
|
+
85j2jH+/sYHLetr4VbSNTfQBXcOmWltW7l8ABePXt0uEUbE2NYuPQNOu0QIDAQAB
|
5
|
+
AoGAE4MZlp/JNxlbB5TvcIbdAA1t8de8A3QfjU+mXBJi9vhx8e9+rAuVUurboLX8
|
6
|
+
1il9sKMgG7CTV0qSR419ZUsi8ndJW5Lg4V3jLDJ4iSnNH4L7DWs7ZyoYq4Z0Rkav
|
7
|
+
lZJbvFo0dsl9ntWAgioemEhul7d+OYI2/Rzrn1Kulqb/EQECQQDxWB5iphmyhIiq
|
8
|
+
rSF344TXoFKHEKL6+EQbknPh2WkhFxzkx53/oKm3IszjbMkixOrmIYbxRyhXWL7c
|
9
|
+
WJ1fBOkpAkEA2lrI8pHo7k5qkFc9RBpjUiPqEhl9ZO+W8tS0XS45uCpxM+Z3Di9k
|
10
|
+
tafzkPIU11oeGrvYa6m5SEkgN34O1DhFaQJAYzkXRPeFGR/kEEeduuyPcRc41s7A
|
11
|
+
Mu5fEfbkLbZ0wmX+OxDWpIIpRGHKWrYe+2x6JqMiF5BpxX92+KB2EtqyAQJAG4U9
|
12
|
+
tnT1arOvcqnMKv04b23fXpCf4UzhNZHhea0N0UxoICZ38u2+P7b/V9FrFwlgqfXq
|
13
|
+
/QbTN20gBl549/5voQJAQPC7y93eEL73CY6FTNqETMrIT8dVmaAnQkvbk55Ratqv
|
14
|
+
XwxN+/Ec8Nvu12fTO+dYrf7IW6kbZ0zZ3pCQUIYsQQ==
|
15
|
+
-----END RSA PRIVATE KEY-----
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'activerecord'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
ENV['RAILS_ENV'] = 'test'
|
7
|
+
require File.dirname(__FILE__) + '/../lib/acts_as_encryptable'
|
8
|
+
|
9
|
+
class Test::Unit::TestCase
|
10
|
+
|
11
|
+
def establish_connection(db_file = nil)
|
12
|
+
db_file = File.join('/tmp/acts_as_encryptable_tests.sqlite') unless db_file
|
13
|
+
ActiveRecord::Base.configurations = { 'ActiveRecord::Base' => { :adapter => 'sqlite3', :database => db_file, :timeout => 5000 } }
|
14
|
+
ActiveRecord::Base.establish_connection('ActiveRecord::Base')
|
15
|
+
ActiveRecord::Base.connection.execute('drop table if exists credit_cards')
|
16
|
+
ActiveRecord::Base.connection.execute('create table credit_cards (id integer, encrypted text)')
|
17
|
+
ActiveRecord::Base.connection.execute('drop table if exists people')
|
18
|
+
ActiveRecord::Base.connection.execute('create table people (id integer, important_data text)')
|
19
|
+
ActiveRecord::Base.connection
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class BaseTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class CreditCard < ActiveRecord::Base
|
6
|
+
attr_accessor :name_on_card, :number, :expiration
|
7
|
+
acts_as_encryptable :name_on_card, :number, :expiration
|
8
|
+
end
|
9
|
+
|
10
|
+
class Person < ActiveRecord::Base
|
11
|
+
attr_accessor :first_name, :last_name, :ssn
|
12
|
+
acts_as_encryptable :first_name, :last_name, :ssn, :column => 'important_data'
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup
|
16
|
+
@connection = establish_connection
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_a_credit_card
|
20
|
+
card = CreditCard.new(valid_credit_card)
|
21
|
+
assert card.save
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_data_is_encrypted
|
25
|
+
test_a_credit_card
|
26
|
+
card = CreditCard.last
|
27
|
+
assert !card.name_on_card
|
28
|
+
assert !card.number
|
29
|
+
assert !card.expiration
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_data_is_decrypted
|
33
|
+
test_a_credit_card
|
34
|
+
card = CreditCard.last
|
35
|
+
card.decrypt!
|
36
|
+
assert card.name_on_card == valid_credit_card[:name_on_card]
|
37
|
+
assert card.number == valid_credit_card[:number]
|
38
|
+
assert card.expiration == valid_credit_card[:expiration]
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_set_encrypted_column_name
|
42
|
+
person = Person.new(valid_person)
|
43
|
+
assert person.save!
|
44
|
+
person = Person.last
|
45
|
+
person.decrypt!
|
46
|
+
assert person.first_name = valid_person[:first_name]
|
47
|
+
assert person.last_name = valid_person[:last_name]
|
48
|
+
assert person.ssn = valid_person[:ssn]
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def valid_credit_card
|
54
|
+
{
|
55
|
+
:name_on_card => 'Test User',
|
56
|
+
:number => '1234567890123456',
|
57
|
+
:expiration => (Date.today + 1.year).strftime("%i/%y")
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def valid_person
|
62
|
+
{
|
63
|
+
:first_name => 'Test',
|
64
|
+
:last_name => 'User',
|
65
|
+
:ssn => '111223333'
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class CryptoTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@text = "I am a secret"
|
7
|
+
@public_key = File.join(File.dirname(__FILE__), '/../../sample_keys/rsa_key.pub')
|
8
|
+
@private_key = File.join(File.dirname(__FILE__), '/../../sample_keys/rsa_key')
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_encryption
|
12
|
+
public_key = ActsAsEncryptable::Crypto::Key.from_file(@public_key)
|
13
|
+
encrypted = public_key.encrypt(@text)
|
14
|
+
assert encrypted != @text
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_decryption
|
18
|
+
public_key = ActsAsEncryptable::Crypto::Key.from_file(@public_key)
|
19
|
+
private_key = ActsAsEncryptable::Crypto::Key.from_file(@private_key)
|
20
|
+
encrypted = public_key.encrypt(@text)
|
21
|
+
assert @text == private_key.decrypt(encrypted)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ssoper-acts_as_encryptable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sean Soper
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-03-27 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: capistrano
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.5.0
|
24
|
+
version:
|
25
|
+
description: Allow your models to encrypt an arbitrary amount of data using asymmetric keys
|
26
|
+
email: sean.soper@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- MIT-LICENSE
|
33
|
+
- README.rdoc
|
34
|
+
files:
|
35
|
+
- acts_as_encryptable.gemspec
|
36
|
+
- lib/acts_as_encryptable.rb
|
37
|
+
- lib/acts_as_encryptable/base.rb
|
38
|
+
- lib/acts_as_encryptable/crypto.rb
|
39
|
+
- generators/acts_as_encryptable_migration/acts_as_encryptable_migration_generator.rb
|
40
|
+
- sample_keys/rsa_key.pub
|
41
|
+
- sample_keys/rsa_key
|
42
|
+
- test/test_helper.rb
|
43
|
+
- test/unit/base_test.rb
|
44
|
+
- test/unit/crypto_test.rb
|
45
|
+
- MIT-LICENSE
|
46
|
+
- Rakefile
|
47
|
+
- README.rdoc
|
48
|
+
- Changelog
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: http://github.com/ssoper/acts_as_encryptable
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options:
|
53
|
+
- --line-numbers
|
54
|
+
- --inline-source
|
55
|
+
- --title
|
56
|
+
- acts_as_encryptable
|
57
|
+
- --main
|
58
|
+
- README.rdoc
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: "0"
|
72
|
+
version:
|
73
|
+
requirements: []
|
74
|
+
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 1.2.0
|
77
|
+
signing_key:
|
78
|
+
specification_version: 2
|
79
|
+
summary: Encrypt and decrypt your data using asymmetric keys
|
80
|
+
test_files: []
|
81
|
+
|