spikex-strongbox 0.1.3 → 0.1.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/Rakefile +1 -1
- data/lib/strongbox/lock.rb +17 -6
- data/lib/strongbox.rb +1 -1
- metadata +2 -7
- data/test/database.yml +0 -4
- data/test/fixtures/keypair.pem +0 -24
- data/test/strongbox_test.rb +0 -126
- data/test/test_helper.rb +0 -50
data/Rakefile
CHANGED
@@ -31,7 +31,7 @@ spec = Gem::Specification.new do |s|
|
|
31
31
|
s.authors = ["Spike Ilacqua"]
|
32
32
|
s.email = "spike@stuff-things.net"
|
33
33
|
s.homepage = "http://stuff-things.net/strongbox"
|
34
|
-
s.files = FileList["[A-Z]*", "init.rb", "{lib,rails
|
34
|
+
s.files = FileList["[A-Z]*", "init.rb", "{lib,rails}/**/*"]
|
35
35
|
s.add_development_dependency 'thoughtbot-shoulda'
|
36
36
|
end
|
37
37
|
|
data/lib/strongbox/lock.rb
CHANGED
@@ -36,9 +36,14 @@ module Strongbox
|
|
36
36
|
|
37
37
|
ciphertext = cipher.update(plaintext)
|
38
38
|
ciphertext << cipher.final
|
39
|
-
|
40
|
-
|
41
|
-
@
|
39
|
+
encrypted_key = public_key.public_encrypt(random_key,@padding)
|
40
|
+
encrypted_iv = public_key.public_encrypt(random_iv,@padding)
|
41
|
+
if @base64
|
42
|
+
encrypted_key = Base64.encode64(encrypted_key)
|
43
|
+
encrypted_iv = Base64.encode64(encrypted_iv)
|
44
|
+
end
|
45
|
+
@instance.write_attribute(@symmetric_key,encrypted_key)
|
46
|
+
@instance.write_attribute(@symmetric_iv,encrypted_iv)
|
42
47
|
else
|
43
48
|
ciphertext = public_key.public_encrypt(plaintext,@padding)
|
44
49
|
end
|
@@ -63,11 +68,17 @@ module Strongbox
|
|
63
68
|
if ciphertext
|
64
69
|
ciphertext = Base64.decode64(ciphertext) if @base64
|
65
70
|
private_key = OpenSSL::PKey::RSA.new(File.read(@private_key),password)
|
66
|
-
if @symmetric == :always
|
71
|
+
if @symmetric == :always
|
72
|
+
random_key = @instance.read_attribute(@symmetric_key)
|
73
|
+
random_iv = @instance.read_attribute(@symmetric_iv)
|
74
|
+
if @base64
|
75
|
+
random_key = Base64.decode64(random_key)
|
76
|
+
random_iv = Base64.decode64(random_iv)
|
77
|
+
end
|
67
78
|
cipher = OpenSSL::Cipher::Cipher.new(@symmetric_cipher)
|
68
79
|
cipher.decrypt
|
69
|
-
cipher.key = private_key.private_decrypt(
|
70
|
-
cipher.iv = private_key.private_decrypt(
|
80
|
+
cipher.key = private_key.private_decrypt(random_key,@padding)
|
81
|
+
cipher.iv = private_key.private_decrypt(random_iv,@padding)
|
71
82
|
plaintext = cipher.update(ciphertext)
|
72
83
|
plaintext << cipher.final
|
73
84
|
else
|
data/lib/strongbox.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spikex-strongbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Spike Ilacqua
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-04-
|
12
|
+
date: 2009-04-16 23:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -39,11 +39,6 @@ files:
|
|
39
39
|
- lib/strongbox/lock.rb
|
40
40
|
- lib/strongbox.rb
|
41
41
|
- rails/init.rb
|
42
|
-
- test/database.yml
|
43
|
-
- test/fixtures
|
44
|
-
- test/fixtures/keypair.pem
|
45
|
-
- test/strongbox_test.rb
|
46
|
-
- test/test_helper.rb
|
47
42
|
has_rdoc: false
|
48
43
|
homepage: http://stuff-things.net/strongbox
|
49
44
|
post_install_message:
|
data/test/database.yml
DELETED
data/test/fixtures/keypair.pem
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
-----BEGIN RSA PRIVATE KEY-----
|
2
|
-
Proc-Type: 4,ENCRYPTED
|
3
|
-
DEK-Info: DES-EDE3-CBC,317921A00FB0882F
|
4
|
-
|
5
|
-
f+GWBkcLJLsBUElOEKhqrtYgT1X4nixaZHD5x0VhmW2FrREz4vcqXrxwLTaRQJK/
|
6
|
-
vHFJ/7IVmEHScwEognSfw/wX2HMIHczoQT3ugsa29Nt7t1VLGy9jvN1+1f+g90xe
|
7
|
-
02jC7CYEKUJ3agZPox49i0/UN9OCIgdtKfecdDHYWyziob8yYTsUdDGyAXlPv0Kx
|
8
|
-
0MPSCRDtEh4UJ2PIFyw2HowkYeNss6uIte9rxJGINI11D9vmXR0pH0XyCwHQn+2T
|
9
|
-
ScHWg8BJ1rkBKydbKQ4vnfhGMjG+bZyrJXrJSoazXroseuhHu8QRUONm5Kl/zW1f
|
10
|
-
GP1CjIfTCQQZECYIa2tXTFdL9y2ZOCn8xit57SwEpmJMvZC58PkQX5+/aHPcOXhl
|
11
|
-
YrF+6FEfNpdBz9PUmv4Af2kTa88xZqm1Q3GtTOk7wsJpfeTMhU71KjA1pL9xNPrT
|
12
|
-
DnKhtfLGvcgo8Z9BGOiLFe9uQvhhprX7isc1XdysbMigsVIWLvZp9RxRp/zAn7fy
|
13
|
-
y56C6mc3tUwcq89RcxAn+bC75gwZO/hyVrnkhManOMfHTEiZXVybU9Ril3SZ+ry6
|
14
|
-
8AxMid0ZWbbtCHdDc5rHfXsGeFhJZxBbg/WtMxBPGHNByqs8sWUM9Z8YoK8WMYxV
|
15
|
-
GvC9RB4m0jgA4S3MEOMmKOXDuJxa7IgTgApVmLPl+sDOHGK3xAItYJJawJqOZQ1f
|
16
|
-
r+x/8g19CuehuflCxDo+D4/RJMqkOEq+0FGUqI8lHv6vR6+YpkGdrQQXUohBy67f
|
17
|
-
3Qym1ztZ8ygsttgJwnhwAfMh8FdIrVJc7NZ8pDiBZbg=
|
18
|
-
-----END RSA PRIVATE KEY-----
|
19
|
-
-----BEGIN PUBLIC KEY-----
|
20
|
-
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9F1ipsLL+V68bGSJFqFLQKgXq
|
21
|
-
Glyyplx0s9KxgLbmbDICXpV7DceKaIBUkPZDx2DrlvjZmG+rG5ehdWNI7q/hupao
|
22
|
-
NF0WzEiOp+30gISeyl81Z/NAmhcwcOnZpbS9nl4JLaWrN7iGC1geNBNDo+lVbsm1
|
23
|
-
O2+Tlt8rjHsNjzgIzQIDAQAB
|
24
|
-
-----END PUBLIC KEY-----
|
data/test/strongbox_test.rb
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
require 'test/test_helper'
|
2
|
-
|
3
|
-
class StrongboxTest < Test::Unit::TestCase
|
4
|
-
context "A Class with a secured field" do
|
5
|
-
setup do
|
6
|
-
rebuild_model :key_pair => File.join(FIXTURES_DIR,'keypair.pem')
|
7
|
-
end
|
8
|
-
|
9
|
-
should "not error when trying to also create a secure field" do
|
10
|
-
assert_nothing_raised do
|
11
|
-
Dummy.class_eval do
|
12
|
-
encrypt_with_public_key :secret,
|
13
|
-
:key_pair => File.join(FIXTURES_DIR,'keypair.pem')
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
context "that is valid" do
|
19
|
-
setup do
|
20
|
-
@dummy = Dummy.new
|
21
|
-
@dummy.secret = 'Shhhh'
|
22
|
-
@dummy.in_the_clear = 'Hey you guys!'
|
23
|
-
end
|
24
|
-
|
25
|
-
should "not change unencrypted fields" do
|
26
|
-
assert_equal 'Hey you guys!', @dummy.in_the_clear
|
27
|
-
end
|
28
|
-
|
29
|
-
should "return '*encrypted*' when locked" do
|
30
|
-
assert_equal "*encrypted*", @dummy.secret.decrypt
|
31
|
-
end
|
32
|
-
|
33
|
-
should "return secret when unlocked" do
|
34
|
-
assert_equal "Shhhh", @dummy.secret.decrypt('boost facile')
|
35
|
-
end
|
36
|
-
|
37
|
-
should "generate and store symmetric encryption key and IV" do
|
38
|
-
assert_not_nil @dummy.attributes['secret_key']
|
39
|
-
assert_not_nil @dummy.attributes['secret_iv']
|
40
|
-
end
|
41
|
-
|
42
|
-
should "raise on bad password" do
|
43
|
-
assert_raises(OpenSSL::PKey::RSAError) do
|
44
|
-
@dummy.secret.decrypt('letmein')
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
context "with symmetric encryption disabled" do
|
49
|
-
setup do
|
50
|
-
rebuild_class(:key_pair => File.join(FIXTURES_DIR,'keypair.pem'),
|
51
|
-
:symmetric => :never)
|
52
|
-
@dummy = Dummy.new
|
53
|
-
@dummy.secret = 'Shhhh'
|
54
|
-
end
|
55
|
-
|
56
|
-
should "return '*encrypted*' when locked" do
|
57
|
-
assert_equal "*encrypted*", @dummy.secret.decrypt
|
58
|
-
end
|
59
|
-
|
60
|
-
should "return secret when unlocked" do
|
61
|
-
assert_equal "Shhhh", @dummy.secret.decrypt('boost facile')
|
62
|
-
end
|
63
|
-
|
64
|
-
should "not generate and store symmetric encryption key and IV" do
|
65
|
-
assert_nil @dummy.attributes['secret_key']
|
66
|
-
assert_nil @dummy.attributes['secret_iv']
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
context "with Base64 encoding enabled" do
|
72
|
-
setup do
|
73
|
-
rebuild_class(:key_pair => File.join(FIXTURES_DIR,'keypair.pem'),
|
74
|
-
:base64 => true)
|
75
|
-
@dummy = Dummy.new
|
76
|
-
@dummy.secret = 'Shhhh'
|
77
|
-
end
|
78
|
-
|
79
|
-
should 'Base64 encode the ciphertext' do
|
80
|
-
# Base64 encoded text is limited to the charaters A–Z, a–z, and 0–9,
|
81
|
-
# and is padded with 0 to 2 equal-signs
|
82
|
-
assert_match /^[0-9A-Za-z+\/]+={0,2}$/, @dummy.attributes['secret']
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
context "using blowfish cipher instead of AES" do
|
88
|
-
setup do
|
89
|
-
rebuild_class(:key_pair => File.join(FIXTURES_DIR,'keypair.pem'),
|
90
|
-
:symmetric_cipher => 'bf-cbc')
|
91
|
-
@dummy = Dummy.new
|
92
|
-
@dummy.secret = 'Shhhh'
|
93
|
-
end
|
94
|
-
|
95
|
-
should "encrypt the data" do
|
96
|
-
assert_not_equal @dummy.attributes['secret'], 'Shhhh'
|
97
|
-
assert_equal "*encrypted*", @dummy.secret.decrypt
|
98
|
-
assert_equal "Shhhh", @dummy.secret.decrypt('boost facile')
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
context "when a key_pair is not provided" do
|
104
|
-
setup do
|
105
|
-
rebuild_class
|
106
|
-
@dummy = Dummy.new
|
107
|
-
end
|
108
|
-
|
109
|
-
should "raise on encrypt" do
|
110
|
-
assert_raises(Strongbox::StrongboxError) do
|
111
|
-
@dummy.secret = 'Shhhh'
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
should "raise on decrypt with a password" do
|
116
|
-
assert_raises(Strongbox::StrongboxError) do
|
117
|
-
@dummy.secret.decrypt('boost facile')
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
should "return '*encrypted*' when still locked" do
|
122
|
-
assert_equal "*encrypted*", @dummy.secret.decrypt
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
data/test/test_helper.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
ROOT = File.join(File.dirname(__FILE__), '..')
|
2
|
-
RAILS_ROOT = ROOT
|
3
|
-
$LOAD_PATH << File.join(ROOT, 'lib')
|
4
|
-
|
5
|
-
require 'rubygems'
|
6
|
-
require 'test/unit'
|
7
|
-
require 'activerecord'
|
8
|
-
gem 'thoughtbot-shoulda', ">= 2.9.0"
|
9
|
-
require 'shoulda'
|
10
|
-
begin require 'redgreen'; rescue LoadError; end
|
11
|
-
|
12
|
-
require 'strongbox'
|
13
|
-
|
14
|
-
ENV['RAILS_ENV'] ||= 'test'
|
15
|
-
|
16
|
-
FIXTURES_DIR = File.join(File.dirname(__FILE__), "fixtures")
|
17
|
-
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
18
|
-
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
19
|
-
ActiveRecord::Base.establish_connection(config['test'])
|
20
|
-
|
21
|
-
|
22
|
-
# rebuild_model and rebuild_class are borrowed directly from the Paperclip gem
|
23
|
-
#
|
24
|
-
# http://thoughtbot.com/projects/paperclip
|
25
|
-
|
26
|
-
# rebuild_model (re)creates a database table for our Dummy model.
|
27
|
-
# Call this to initial create a model, or to reset the database.
|
28
|
-
|
29
|
-
def rebuild_model options = {}
|
30
|
-
ActiveRecord::Base.connection.create_table :dummies, :force => true do |table|
|
31
|
-
table.string :in_the_clear
|
32
|
-
table.binary :secret
|
33
|
-
table.binary :secret_key
|
34
|
-
table.binary :secret_iv
|
35
|
-
end
|
36
|
-
rebuild_class options
|
37
|
-
end
|
38
|
-
|
39
|
-
# rebuild_class creates or replaces the Dummy ActiveRecord Model.
|
40
|
-
# Call this when changing the options to encrypt_with_public_key
|
41
|
-
|
42
|
-
def rebuild_class options = {}
|
43
|
-
ActiveRecord::Base.send(:include, Strongbox)
|
44
|
-
Object.send(:remove_const, "Dummy") rescue nil
|
45
|
-
Object.const_set("Dummy", Class.new(ActiveRecord::Base))
|
46
|
-
Dummy.class_eval do
|
47
|
-
include Strongbox
|
48
|
-
encrypt_with_public_key :secret, options
|
49
|
-
end
|
50
|
-
end
|