symmetric-encryption 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -3,7 +3,7 @@ symmetric-encryption
3
3
 
4
4
  * http://github.com/ClarityServices/symmetric-encryption
5
5
 
6
- ### Introduction
6
+ ## Introduction
7
7
 
8
8
  Any project that wants to meet PCI compliance has to ensure that the data is encrypted
9
9
  whilst in flight and at rest. Amongst many other other requirements all passwords
@@ -12,24 +12,288 @@ in configuration files have to be encrypted
12
12
  This Gem helps achieve compliance by supporting encryption of data in a simple
13
13
  and consistent way
14
14
 
15
- ### Features
15
+ ## Security
16
+
17
+ Many solutions that encrypt data require the encryption keys to be stored in the
18
+ applications source code or leave it up to the developer to secure the keys on
19
+ the application servers. symmetric-encryption takes care of securing the
20
+ symmetric encryption keys.
21
+
22
+ The following steps are used to secure the symmetric encryption keys using symmetric-encryption:
23
+
24
+ * Symmetric Encryption keys are stored in files that are not part of the application,
25
+ its source code, or even stored in its source control system. These files can be
26
+ created, managed and further secured by System Administrators. This prevents
27
+ developers having or needing to have access to the symmetric encryption keys
28
+ * The Operating System security features limit access to the Symmetric Encryption
29
+ key files to System Administrators and the userid under which the Rails application runs.
30
+ * The files in which the Symmetric Encryption keys are stored are futher
31
+ encrypted using RSA 2048 bit encryption
32
+
33
+ In order for anyone to decrypt the data being encrypted in the database, they
34
+ would need access to ALL of the following:
35
+ * A copy of the files containing the Symmetric Encryption Keys which are secured
36
+ by the Operating System
37
+ * The application source code containing the RSA private key to decrypt the above files
38
+ * The userid and password for the database to copy the encrypted data itself,
39
+ or an unsecured copy or export of the database contents
40
+
41
+ ## Features
16
42
 
17
43
  * Encryption of passwords in configuration files
18
- * attr_encrypted replacement
44
+ * Encryption of ActiveRecord model attributes by prefixing attributes / column
45
+ names with encrypted_
19
46
  * Externalization of symmetric encryption keys so that they are not in the
20
- source code
47
+ source code, or the source code control system
48
+ * Drop in replacement for attr_encrypted. Just remove the attr_encrypted gem
49
+ * Compatible with the default Encryption algorithm in attr_encrypted
50
+ * More efficient replacement for attr_encrypted since only ActiveRecord Models
51
+ are extended with encrypted_ behavior, rather than every object in the system
52
+ * Custom validator for ActiveRecord Models
53
+
54
+ ## Examples
55
+
56
+ ### Encryption Example
57
+
58
+ Symmetric::Encryption.encrypt "Sensitive data"
59
+
60
+ ### Decryption Example
61
+
62
+ Symmetric::Encryption.decrypt "JqLJOi6dNjWI9kX9lSL1XQ==\n"
63
+
64
+ ### Validation Example
65
+
66
+ class MyModel < ActiveRecord::Base
67
+ validates :encrypted_ssn, :symmetric_encrypted => true
68
+ end
69
+
70
+ m = MyModel.new
71
+ m.valid?
72
+ # => false
73
+ m.encrypted_ssn = Symmetric::Encryption.encrypt('123456789')
74
+ m.valid?
75
+ # => true
76
+
77
+ ### Encrypting Passwords in configuration files
78
+
79
+ Passwords can be encrypted in any YAML configuration file.
80
+
81
+ For example config/database.yml
82
+
83
+ production:
84
+ adapter: mysql
85
+ host: db1w
86
+ database: myapp_production
87
+ username: admin
88
+ password: <%= Symmetric::Encryption.try_decrypt "JqLJOi6dNjWI9kX9lSL1XQ==\n" %>
89
+
90
+ Note: Use Symmetric::Encryption.try_decrypt method which will return nil if it
91
+ fails to decrypt the value, which is essential when the encryption keys differ
92
+ between environments
93
+
94
+ Note: In order for the above technique to work in other YAML configuration files
95
+ the YAML file must be processed using ERB prior to passing to YAML. For example
21
96
 
22
- ### Install
97
+ config_file = Rails.root.join('config', 'redis.yml')
98
+ raise "redis config not found. Create a config file at: config/redis.yml" unless config_file.file?
99
+
100
+ cfg = YAML.load(ERB.new(File.new(config_file).read).result)[Rails.env]
101
+ raise("Environment #{Rails.env} not defined in redis.yml") unless cfg
102
+
103
+ ### Generating encrypted passwords
104
+
105
+ The following rake task can be used to generate encrypted passwords for the
106
+ specified environment
107
+
108
+ Note: Passwords must be encrypted in the environment in which they will be used.
109
+ Since each environment should have its own symmetric encryption keys
110
+
111
+ ## Install
23
112
 
24
113
  gem install symmetric-encryption
25
114
 
115
+ ## Configuration
116
+
117
+ ### Generating the RSA Private key
118
+
119
+ To protect the files holding the Symmetric Encryption keys, symmetric-encryption uses 2048 bit RSA
120
+ encryption.
121
+
122
+ Generate the RSA Private key as follows
123
+
124
+ openssl genrsa 2048
125
+
126
+ Paste the output into the configuration created below
127
+
128
+ ### Creating the configuration file
129
+
130
+ Create a configuration file in config/symmetric-encryption.yml per the following example:
131
+
132
+ #
133
+ # Symmetric Encryption for Ruby
134
+ #
135
+ ---
136
+ # Just use test symmetric encryption keys in the development environment
137
+ # No private key required since we are not reading the keys from a file
138
+ development: &development_defaults
139
+ cipher: aes-256-cbc
140
+ symmetric_key: 1234567890ABCDEF1234567890ABCDEF
141
+ symmetric_iv: 1234567890ABCDEF
142
+
143
+ test:
144
+ <<: *development_defaults
145
+
146
+ release: &release_defaults
147
+ # Since the key to encrypt and decrypt with must NOT be stored along with the
148
+ # source code, we only hold a RSA key that is used to unlock the file
149
+ # containing the actual symmetric encryption key
150
+ #
151
+ # To generate a new RSA private key:
152
+ # openssl genrsa 2048
153
+ private_rsa_key: |
154
+ -----BEGIN RSA PRIVATE KEY-----
155
+ ...
156
+ paste RSA key generated above here
157
+ ...
158
+ -----END RSA PRIVATE KEY-----
159
+
160
+ # Filename containing Symmetric Encryption Key
161
+ # Note: The file contents must be RSA 2048 bit encrypted
162
+ # with the public key derived from the private key above
163
+ symmetric_key_filename: /etc/rails/.rails.key
164
+ symmetric_iv_filename: /etc/rails/.rails.iv
165
+
166
+ # Use aes-256-cbc encryption
167
+ cipher: aes-256-cbc
168
+
169
+ hotfix:
170
+ <<: *release_defaults
171
+
172
+ production:
173
+ <<: *release_defaults
174
+
175
+ This configuration file should be checked into the source code control system.
176
+ It does Not include the Symmetric Encryption keys. They will be generated in the
177
+ next step.
178
+
179
+ ### Generating and securing the Symmetric Encryption keys
180
+
181
+ The symmetric encryption key consists of the key itself and an optional
182
+ initialization vector.
183
+
184
+ To generate the keys run the following Rake task in each environment:
185
+
186
+ RAILS_ENV=release rake symmetric_encryption:generate_symmetric_keys
187
+
188
+ Replace 'release' as necessary for each environment.
189
+
190
+ Make sure that the current user has read and write access to the folder listed
191
+ in the configuration option symmetric_key_filename above.
192
+
193
+ Once the Symmetric Encryption keys have been generated, secure them further by
194
+ making the files read-only to the Rails user and not readable by any other user
195
+
196
+ chmod ...
197
+
198
+ When running multiple Rails servers in a particular environment copy the same
199
+ key files to every server in that environment. I.e. All Rails servers in each
200
+ environment must run the same encryption keys.
201
+
202
+ Note: The generate step above must only be run once in each environment
203
+
204
+ ## Using in non-Rails environments
205
+
206
+ symmetric-encryption can also be used in non-Rails environment. At application
207
+ startup, run the code below to initialize symmetric-encryption prior to
208
+ attempting to encrypt or decrypt any data
209
+
210
+ require 'symmetric-encryption'
211
+ Symmetric::Encryption.load!('config/symmetric-encryption.yml', 'production')
212
+
213
+ Parameters:
214
+ * Filename of the configuration file created above
215
+ * Name of the environment to load the configuration for
216
+
217
+ To manually generate the symmetric encryption keys, run the code below
218
+
219
+ require 'symmetric-encryption'
220
+ Symmetric::Encryption.generate_symmetric_key_files('config/symmetric-encryption.yml', 'production')
221
+
222
+ Parameters:
223
+ * Filename of the configuration file created above
224
+ * Name of the environment to load the configuration for
225
+
226
+ ## Supporting Multiple Encryption Keys
227
+
228
+ For complete PCI compliance it is necessary to change the Symmetric Encryption
229
+ keys every year. During the transition period of moving from one encryption
230
+ key to another symmetric-encryption supports multiple Symmetric Encryption keys.
231
+ If decryption with the current key fails, any previous keys will also be tried
232
+ automatically.
233
+
234
+ By default the latest key is used for encrypting data. Another key can be specified
235
+ for encryption so that old data can be looked in queries, etc.
236
+
237
+ Since just the Symmetric Encryption keys are being changed, we can still continue to
238
+ use the same RSA Private key for gaining access to the Symmetric Encryption Keys
239
+
240
+ ### Configuring multiple Symmetric Encryption keys
241
+
242
+
243
+
244
+ Create a configuration file in config/symmetric-encryption.yml per the following example:
245
+
246
+ #
247
+ # Symmetric Encryption for Ruby
248
+ #
249
+ ---
250
+ # Just use test symmetric encryption keys in the development environment
251
+ # No private key required since we are not reading the keys from a file
252
+ development: &development_defaults
253
+ cipher: aes-256-cbc
254
+ symmetric_key: 1234567890ABCDEF1234567890ABCDEF
255
+ symmetric_iv: 1234567890ABCDEF
256
+
257
+ test:
258
+ <<: *development_defaults
259
+
260
+ release: &release_defaults
261
+ # Since the key to encrypt and decrypt with must NOT be stored along with the
262
+ # source code, we only hold a RSA key that is used to unlock the file
263
+ # containing the actual symmetric encryption key
264
+ #
265
+ # To generate a new RSA private key:
266
+ # openssl genrsa 2048
267
+ private_rsa_key: |
268
+ -----BEGIN RSA PRIVATE KEY-----
269
+ ...
270
+ paste RSA key generated above here
271
+ ...
272
+ -----END RSA PRIVATE KEY-----
273
+
274
+ # Filename containing Symmetric Encryption Key
275
+ # Note: The file contents must be RSA 2048 bit encrypted
276
+ # with the public key derived from the private key above
277
+ symmetric_key_filename: /etc/rails/.rails.key
278
+ symmetric_iv_filename: /etc/rails/.rails.iv
279
+
280
+ # Use aes-256-cbc encryption
281
+ cipher: aes-256-cbc
282
+
283
+ hotfix:
284
+ <<: *release_defaults
285
+
286
+ production:
287
+ <<: *release_defaults
288
+
289
+
290
+
26
291
  Meta
27
292
  ----
28
293
 
29
294
  * Code: `git clone git://github.com/ClarityServices/symmetric-encryption.git`
30
295
  * Home: <https://github.com/ClarityServices/symmetric-encryption>
31
- * Docs: TODO <http://ClarityServices.github.com/symmetric-encryption/>
32
- * Bugs: <http://github.com/reidmorrison/symmetric-encryption/issues>
296
+ * Bugs: <http://github.com/ClarityServices/symmetric-encryption/issues>
33
297
  * Gems: <http://rubygems.org/gems/symmetric-encryption>
34
298
 
35
299
  This project uses [Semantic Versioning](http://semver.org/).
@@ -55,3 +319,10 @@ distributed under the License is distributed on an "AS IS" BASIS,
55
319
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
56
320
  See the License for the specific language governing permissions and
57
321
  limitations under the License.
322
+
323
+ Compliance
324
+ ----------
325
+
326
+ Although this library has assisted Clarity in meeting PCI Compliance it in no
327
+ way guarantees that PCI Compliance will be met by anyone using this library
328
+ for encryption purposes.
@@ -0,0 +1,66 @@
1
+ #
2
+ # Symmetric Encryption for Ruby
3
+ #
4
+ ---
5
+ # Just use test symmetric encryption keys in the development environment
6
+ # No private key required since we are not reading the keys from a file
7
+ development: &development_defaults
8
+ cipher: aes-256-cbc
9
+ symmetric_key: 1234567890ABCDEF1234567890ABCDEF
10
+ symmetric_iv: 1234567890ABCDEF
11
+
12
+ test:
13
+ <<: *development_defaults
14
+
15
+ release: &release_defaults
16
+ # Since the key to encrypt and decrypt with must NOT be stored along with the
17
+ # source code, we only hold a RSA key that is used to unlock the file
18
+ # containing the actual symmetric encryption key
19
+ #
20
+ # To generate a new RSA private key:
21
+ # openssl genrsa 2048
22
+
23
+ # Sample RSA Key, do not use this one as is, generate a new one
24
+ private_rsa_key: |
25
+ -----BEGIN RSA PRIVATE KEY-----
26
+ MIIEpAIBAAKCAQEAxIL9H/jYUGpA38v6PowRSRJEo3aNVXULNM/QNRpx2DTf++KH
27
+ 6DcuFTFcNSSSxG9n4y7tKi755be8N0uwCCuOzvXqfWmXYjbLwK3Ib2vm0btpHyvA
28
+ qxgqeJOOCxKdW/cUFLWn0tACUcEjVCNfWEGaFyvkOUuR7Ub9KfhbW9cZO3BxZMUf
29
+ IPGlHl/gWyf484sXygd+S7cpDTRRzo9RjG74DwfE0MFGf9a1fTkxnSgeOJ6asTOy
30
+ fp9tEToUlbglKaYGpOGHYQ9TV5ZsyJ9jRUyb4SP5wK2eK6dHTxTcHvT03kD90Hv4
31
+ WeKIXv3WOjkwNEyMdpnJJfSDb5oquQvCNi7ZSQIDAQABAoIBAQCbzR7TUoBugU+e
32
+ ICLvpC2wOYOh9kRoFLwlyv3QnH7WZFWRZzFJszYeJ1xr5etXQtyjCnmOkGAg+WOI
33
+ k8GlOKOpAuA/PpB/leJFiYL4lBwU/PmDdTT0cdx6bMKZlNCeMW8CXGQKiFDOcMqJ
34
+ 0uGtH5YD+RChPIEeFsJxnC8SyZ9/t2ra7XnMGiCZvRXIUDSEIIsRx/mOymJ7bL+h
35
+ Lbp46IfXf6ZuIzwzoIk0JReV/r+wdmkAVDkrrMkCmVS4/X1wN/Tiik9/yvbsh/CL
36
+ ztC55eSIEjATkWxnXfPASZN6oUfQPEveGH3HzNjdncjH/Ho8FaNMIAfFpBhhLPi9
37
+ nG5sbH+BAoGBAOdoUyVoAA/QUa3/FkQaa7Ajjehe5MR5k6VtaGtcxrLiBjrNR7x+
38
+ nqlZlGvWDMiCz49dgj+G1Qk1bbYrZLRX/Hjeqy5dZOGLMfgf9eKUmS1rDwAzBMcj
39
+ M9jnnJEBx8HIlNzaR6wzp3GMd0rrccs660A8URvzkgo9qNbvMLq9vyUtAoGBANll
40
+ SY1Iv9uaIz8klTXU9YzYtsfUmgXzw7K8StPdbEbo8F1J3JPJB4D7QHF0ObIaSWuf
41
+ suZqLsvWlYGuJeyX2ntlBN82ORfvUdOrdrbDlmPyj4PfFVl0AK3U3Ai374DNrjKR
42
+ hF6YFm4TLDaJhUjeV5C43kbE1N2FAMS9LYtPJ44NAoGAFDGHZ/E+aCLerddfwwun
43
+ MBS6MnftcLPHTZ1RimTrNfsBXipBw1ItWEvn5s0kCm9X24PmdNK4TnhqHYaF4DL5
44
+ ZjbQK1idEA2Mi8GGPIKJJ2x7P6I0HYiV4qy7fe/w1ZlCXE90B7PuPbtrQY9wO7Ll
45
+ ipJ45X6I1PnyfOcckn8yafUCgYACtPAlgjJhWZn2v03cTbqA9nHQKyV/zXkyUIXd
46
+ /XPLrjrP7ouAi5A8WuSChR/yx8ECRgrEM65Be3qBEtoGCB4AS1G0NcigM6qhKBFi
47
+ VS0aMXr3+V8argcUIwJaWW/x+p2go48yXlJpLHPweeXe8mXEt4iM+QZte6p2yKQ4
48
+ h9PGQQKBgQCqSydmXBnXGIVTp2sH/2GnpxLYnDBpcJE0tM8bJ42HEQQgRThIChsn
49
+ PnGA91G9MVikYapgI0VYBHQOTsz8rTIUzsKwXG+TIaK+W84nxH5y6jUkjqwxZmAz
50
+ r1URaMAun2PfAB4g2N/kEZTExgeOGqXjFhvvjdzl97ux2cTyZhaTXg==
51
+ -----END RSA PRIVATE KEY-----
52
+
53
+ # Filename containing Symmetric Encryption Key
54
+ # Note: The file contents must be RSA 2048 bit encrypted
55
+ # with the public key derived from the private key above
56
+ symmetric_key_filename: /etc/rails/.rails.key
57
+ symmetric_iv_filename: /etc/rails/.rails.iv
58
+
59
+ # Use aes-256-cbc encryption
60
+ cipher: aes-256-cbc
61
+
62
+ hotfix:
63
+ <<: *release_defaults
64
+
65
+ production:
66
+ <<: *release_defaults
@@ -2,5 +2,8 @@ require 'symmetric/version'
2
2
  require 'symmetric/encryption'
3
3
  if defined?(Rails)
4
4
  require 'symmetric/railtie'
5
- require "symmetric/extensions/active_record/base"
5
+ end
6
+ if defined?(ActiveRecord::Base)
7
+ require 'symmetric/extensions/active_record/base'
8
+ require 'symmetric/railties/symmetric_encrypted_validator'
6
9
  end
@@ -1,6 +1,7 @@
1
1
  require 'base64'
2
2
  require 'openssl'
3
3
  require 'zlib'
4
+ require 'yaml'
4
5
 
5
6
  module Symmetric
6
7
 
@@ -16,6 +17,27 @@ module Symmetric
16
17
  MAGIC_HEADER_SIZE = MAGIC_HEADER.size
17
18
  end
18
19
 
20
+ # The minimum length for an encrypted string
21
+ def self.min_encrypted_length
22
+ @@min_encrypted_length ||= encrypt('1').length
23
+ end
24
+
25
+ # Returns [true|false] a best effort determination as to whether the supplied
26
+ # string is encrypted or not, without incurring the penalty of actually
27
+ # decrypting the supplied data
28
+ # Parameters:
29
+ # encrypted_data: Encrypted string
30
+ def self.encrypted?(encrypted_data)
31
+ # Simple checks first
32
+ return false if (encrypted_data.length < min_encrypted_length) || (!encrypted_data.end_with?("\n"))
33
+ # For now have to decrypt it fully
34
+ begin
35
+ decrypt(encrypted_data) ? true : false
36
+ rescue
37
+ false
38
+ end
39
+ end
40
+
19
41
  # Set the Symmetric Cipher to be used
20
42
  def self.cipher=(cipher)
21
43
  @@cipher = cipher
@@ -55,8 +77,9 @@ module Symmetric
55
77
  self.key = symmetric_key
56
78
  self.iv = symmetric_iv
57
79
  else
58
- self.load_keys(config['symmetric_key_filename'], config['symmetric_iv_filename'], config['private_rsa_key'])
80
+ load_keys(config['symmetric_key_filename'], config['symmetric_iv_filename'], config['private_rsa_key'])
59
81
  end
82
+ true
60
83
  end
61
84
 
62
85
  # Load the symmetric key to use for encrypting and decrypting data
@@ -28,7 +28,7 @@ module Symmetric #:nodoc:
28
28
  #
29
29
  # Loaded before Active Record initializes since database.yml can have encrypted
30
30
  # passwords in it
31
- initializer "load symmetry encryption keys" , :before=>"active_record.initialize_database" do
31
+ initializer "load symmetric encryption keys" , :before=>"active_record.initialize_database" do
32
32
  config_file = Rails.root.join("config", "symmetric-encryption.yml")
33
33
  if config_file.file?
34
34
  ::Symmetric::Encryption.load!(config_file, Rails.env)
@@ -0,0 +1,18 @@
1
+ # Add an ActiveModel Validator
2
+ #
3
+ # Example:
4
+ # class MyModel < ActiveRecord::Base
5
+ # validates :encrypted_ssn, :symmetric_encrypted => true
6
+ # end
7
+ #
8
+ # m = MyModel.new
9
+ # m.valid?
10
+ # # => false
11
+ # m.encrypted_ssn = Symmetric::Encryption.encrypt('123456789')
12
+ # m.valid?
13
+ # # => true
14
+ class SymmetricEncryptedValidator < ActiveModel::EachValidator
15
+ def validate_each(record, attribute, value)
16
+ record.errors.add(attribute, "must be a value encrypted using Symmetric::Encryption.encrypt") unless Symmetric::Encryption.encrypted?(value)
17
+ end
18
+ end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Symmetric #:nodoc
3
- VERSION = "0.1.2"
3
+ VERSION = "0.2.0"
4
4
  end
Binary file
@@ -0,0 +1,156 @@
1
+ # Allow examples to be run in-place without requiring a gem install
2
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
3
+
4
+ require 'rubygems'
5
+ require 'logger'
6
+ require 'erb'
7
+ require 'test/unit'
8
+ require 'shoulda'
9
+ require 'active_record'
10
+ require 'symmetric-encryption'
11
+
12
+ # #TODO Need to supply the model and migrations for this test
13
+ # Adding to existing AR model User
14
+ # Unit Test for Symmetric::Encryption
15
+ #
16
+
17
+ #ROOT = File.join(File.dirname(__FILE__), '..')
18
+
19
+ #['/lib', '/db'].each do |folder|
20
+ # $:.unshift File.join(ROOT, folder)
21
+ #end
22
+
23
+ ActiveRecord::Base.logger = Logger.new($stderr)
24
+ ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read('test/config/database.yml')).result)
25
+ ActiveRecord::Base.establish_connection('test')
26
+
27
+ #ActiveRecord::Base.connection.create_database 'symmetric_encryption_test', :charset => :utf8
28
+ #require 'db/schema'
29
+
30
+ #The file db/schema.rb contains, for example:
31
+
32
+ ActiveRecord::Schema.define :version => 0 do
33
+ create_table :users, :force => true do |t|
34
+ t.string :encrypted_bank_account_number
35
+ t.string :encrypted_social_security_number
36
+ end
37
+ end
38
+
39
+ class User < ActiveRecord::Base
40
+ attr_encrypted :bank_account_number
41
+ attr_encrypted :social_security_number
42
+
43
+ validates :encrypted_bank_account_number, :symmetric_encrypted => true
44
+ validates :encrypted_social_security_number, :symmetric_encrypted => true
45
+ end
46
+
47
+ class AttrEncryptedTest < Test::Unit::TestCase
48
+ context 'initialized' do
49
+
50
+ setup do
51
+ Symmetric::Encryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
52
+ end
53
+
54
+ context 'an ActiveRecord environment' do
55
+ setup do
56
+ config_file = File.join(File.dirname(__FILE__), 'config', 'database.yml')
57
+ raise "database config not found. Create a config file at: test/config/database.yml" unless File.exists? config_file
58
+
59
+ cfg = YAML.load(ERB.new(File.new(config_file).read).result)['test']
60
+ raise("Environment 'test' not defined in test/config/database.yml") unless cfg
61
+
62
+ User.establish_connection(cfg)
63
+ end
64
+
65
+ context 'the Symmetric::Encryption Library' do
66
+
67
+ setup do
68
+ @bank_account_number = "1234567890"
69
+ @bank_account_number_encrypted = "QUxoUU8O/mi0o9ykgXNBFg==\n"
70
+
71
+ @social_security_number = "987654321"
72
+ @social_security_number_encrypted = "Jj7dKb3B0aUCnqH/YKGvKw==\n"
73
+
74
+ @user = User.new(
75
+ # Encrypted Attribute
76
+ :bank_account_number => @bank_account_number,
77
+ # Encrypted Attribute
78
+ :social_security_number => @social_security_number
79
+ )
80
+ end
81
+
82
+ should "have encrypted methods" do
83
+ assert_equal true, @user.respond_to?(:encrypted_bank_account_number)
84
+ assert_equal true, @user.respond_to?(:bank_account_number)
85
+ assert_equal true, @user.respond_to?(:encrypted_social_security_number)
86
+ assert_equal true, @user.respond_to?(:social_security_number)
87
+ assert_equal false, @user.respond_to?(:encrypted_name)
88
+ end
89
+
90
+ should "have unencrypted values" do
91
+ assert_equal @bank_account_number, @user.bank_account_number
92
+ assert_equal @social_security_number, @user.social_security_number
93
+ end
94
+
95
+ should "have encrypted values" do
96
+ assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
97
+ assert_equal @social_security_number_encrypted, @user.encrypted_social_security_number
98
+ end
99
+
100
+ should "encrypt" do
101
+ user = User.new
102
+ user.bank_account_number = @bank_account_number
103
+ assert_equal @bank_account_number, user.bank_account_number
104
+ assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
105
+ end
106
+
107
+ should "allow lookups using unencrypted or encrypted column name" do
108
+ @user.save!
109
+
110
+ inq = User.find_by_bank_account_number(@bank_account_number)
111
+ assert_equal @bank_account_number, inq.bank_account_number
112
+ assert_equal @bank_account_number_encrypted, inq.encrypted_bank_account_number
113
+
114
+ @user.delete
115
+ end
116
+
117
+ should "return encrypted attributes for the class" do
118
+ expect = {:social_security_number=>:encrypted_social_security_number, :bank_account_number=>:encrypted_bank_account_number}
119
+ result = User.encrypted_attributes
120
+ expect.each_pair {|k,v| assert_equal expect[k], result[k]}
121
+ end
122
+
123
+ should "return encrypted keys for the class" do
124
+ expect = [:social_security_number, :bank_account_number]
125
+ result = User.encrypted_keys
126
+ expect.each {|val| assert_equal true, result.include?(val)}
127
+
128
+ # Also check encrypted_attribute?
129
+ expect.each {|val| assert_equal true, User.encrypted_attribute?(val)}
130
+ end
131
+
132
+ should "return encrypted columns for the class" do
133
+ expect = [:encrypted_social_security_number, :encrypted_bank_account_number]
134
+ result = User.encrypted_columns
135
+ expect.each {|val| assert_equal true, result.include?(val)}
136
+
137
+ # Also check encrypted_column?
138
+ expect.each {|val| assert_equal true, User.encrypted_column?(val)}
139
+ end
140
+
141
+ should "validate encrypted data" do
142
+ assert_equal true, @user.valid?
143
+ @user.encrypted_bank_account_number = '123'
144
+ assert_equal false, @user.valid?
145
+ assert_equal ["must be a value encrypted using Symmetric::Encryption.encrypt"], @user.errors[:encrypted_bank_account_number]
146
+ @user.encrypted_bank_account_number = Symmetric::Encryption.encrypt('123')
147
+ assert_equal true, @user.valid?
148
+ @user.bank_account_number = '123'
149
+ assert_equal true, @user.valid?
150
+ end
151
+
152
+ end
153
+
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,7 @@
1
+ test:
2
+ database: symmetric_encryption_test
3
+ username: root
4
+ password:
5
+ encoding: utf8
6
+ adapter: mysql
7
+ host: 127.0.0.1
@@ -0,0 +1,43 @@
1
+ #
2
+ # Test Config
3
+ #
4
+ ---
5
+ test:
6
+ # Sample RSA Key, do not use this one as is, generate a new one
7
+ private_rsa_key: |
8
+ -----BEGIN RSA PRIVATE KEY-----
9
+ MIIEpAIBAAKCAQEAxIL9H/jYUGpA38v6PowRSRJEo3aNVXULNM/QNRpx2DTf++KH
10
+ 6DcuFTFcNSSSxG9n4y7tKi755be8N0uwCCuOzvXqfWmXYjbLwK3Ib2vm0btpHyvA
11
+ qxgqeJOOCxKdW/cUFLWn0tACUcEjVCNfWEGaFyvkOUuR7Ub9KfhbW9cZO3BxZMUf
12
+ IPGlHl/gWyf484sXygd+S7cpDTRRzo9RjG74DwfE0MFGf9a1fTkxnSgeOJ6asTOy
13
+ fp9tEToUlbglKaYGpOGHYQ9TV5ZsyJ9jRUyb4SP5wK2eK6dHTxTcHvT03kD90Hv4
14
+ WeKIXv3WOjkwNEyMdpnJJfSDb5oquQvCNi7ZSQIDAQABAoIBAQCbzR7TUoBugU+e
15
+ ICLvpC2wOYOh9kRoFLwlyv3QnH7WZFWRZzFJszYeJ1xr5etXQtyjCnmOkGAg+WOI
16
+ k8GlOKOpAuA/PpB/leJFiYL4lBwU/PmDdTT0cdx6bMKZlNCeMW8CXGQKiFDOcMqJ
17
+ 0uGtH5YD+RChPIEeFsJxnC8SyZ9/t2ra7XnMGiCZvRXIUDSEIIsRx/mOymJ7bL+h
18
+ Lbp46IfXf6ZuIzwzoIk0JReV/r+wdmkAVDkrrMkCmVS4/X1wN/Tiik9/yvbsh/CL
19
+ ztC55eSIEjATkWxnXfPASZN6oUfQPEveGH3HzNjdncjH/Ho8FaNMIAfFpBhhLPi9
20
+ nG5sbH+BAoGBAOdoUyVoAA/QUa3/FkQaa7Ajjehe5MR5k6VtaGtcxrLiBjrNR7x+
21
+ nqlZlGvWDMiCz49dgj+G1Qk1bbYrZLRX/Hjeqy5dZOGLMfgf9eKUmS1rDwAzBMcj
22
+ M9jnnJEBx8HIlNzaR6wzp3GMd0rrccs660A8URvzkgo9qNbvMLq9vyUtAoGBANll
23
+ SY1Iv9uaIz8klTXU9YzYtsfUmgXzw7K8StPdbEbo8F1J3JPJB4D7QHF0ObIaSWuf
24
+ suZqLsvWlYGuJeyX2ntlBN82ORfvUdOrdrbDlmPyj4PfFVl0AK3U3Ai374DNrjKR
25
+ hF6YFm4TLDaJhUjeV5C43kbE1N2FAMS9LYtPJ44NAoGAFDGHZ/E+aCLerddfwwun
26
+ MBS6MnftcLPHTZ1RimTrNfsBXipBw1ItWEvn5s0kCm9X24PmdNK4TnhqHYaF4DL5
27
+ ZjbQK1idEA2Mi8GGPIKJJ2x7P6I0HYiV4qy7fe/w1ZlCXE90B7PuPbtrQY9wO7Ll
28
+ ipJ45X6I1PnyfOcckn8yafUCgYACtPAlgjJhWZn2v03cTbqA9nHQKyV/zXkyUIXd
29
+ /XPLrjrP7ouAi5A8WuSChR/yx8ECRgrEM65Be3qBEtoGCB4AS1G0NcigM6qhKBFi
30
+ VS0aMXr3+V8argcUIwJaWW/x+p2go48yXlJpLHPweeXe8mXEt4iM+QZte6p2yKQ4
31
+ h9PGQQKBgQCqSydmXBnXGIVTp2sH/2GnpxLYnDBpcJE0tM8bJ42HEQQgRThIChsn
32
+ PnGA91G9MVikYapgI0VYBHQOTsz8rTIUzsKwXG+TIaK+W84nxH5y6jUkjqwxZmAz
33
+ r1URaMAun2PfAB4g2N/kEZTExgeOGqXjFhvvjdzl97ux2cTyZhaTXg==
34
+ -----END RSA PRIVATE KEY-----
35
+
36
+ # Filename containing Symmetric Encryption Key
37
+ # Note: The file contents must be RSA 2048 bit encrypted
38
+ # with the public key derived from the private key above
39
+ symmetric_key_filename: test/config/test.key
40
+ symmetric_iv_filename: test/config/test.iv
41
+
42
+ # Use aes-256-cbc encryption
43
+ cipher: aes-256-cbc
@@ -0,0 +1,4 @@
1
+ ��i��pmX�Q"`
2
+ �6;�Y $X<�b��K׶md��Qa�ق�T�(�3�--�/F��w�8�Q�y9�ax�2/i��˹#3E���wX�&J
3
+ �3��l�*�4�t���`�/K�w�(�F����S���qR3b�Т��_މ��f!.�㹐m�����/�����ZܻeX���"�_Z)��R�E�]P@p�"c���/"H�χm�!&��ڜv�v�G�X��#�����ɍ���S>�T?'�L��ȫ����
4
+ �P
@@ -0,0 +1,2 @@
1
+ e@ ���D/�t4��k��"z��Qmg
2
+ m��r��Ն��۪�ӃqE-�}��]��=���8�WzVܮ+�R�nt���R2����.��Iu�l
@@ -4,99 +4,38 @@ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
4
4
  require 'rubygems'
5
5
  require 'test/unit'
6
6
  require 'shoulda'
7
- require 'symmetric-encryption'
8
- require 'yaml'
9
-
10
- # #TODO Need to supply the model and migrations for this test
11
- class User
12
- attr_encrypted :bank_account_number
13
- attr_encrypted :social_security_number
14
- end
15
7
 
16
8
  # Unit Test for Symmetric::Encryption
17
9
  #
18
- class EncryptionTest < ActiveSupport::TestCase
19
- context 'the Symmetric::Encryption Library' do
10
+ class EncryptionTest < Test::Unit::TestCase
11
+ context 'initialized' do
20
12
 
21
13
  setup do
22
- @bank_account_number = "1234567890"
23
- @bank_account_number_encrypted = "V8Dg6zeeIpDg4+qrn2mjlA==\n"
24
-
25
- @social_security_number = "987654321"
26
- @social_security_number_encrypted = "Qd0qzN6oVuATJQBTf8X6tg==\n"
27
-
28
- @user = User.new(
29
- # Encrypted Attribute
30
- :bank_account_number => @bank_account_number,
31
- # Encrypted Attribute
32
- :social_security_number => @social_security_number
33
- )
34
- end
35
-
36
- should "encrypt simple string" do
37
- assert_equal @social_security_number_encrypted, Symmetric::Encryption.encrypt(@social_security_number)
38
- end
39
-
40
- should "decrypt string" do
41
- assert_equal @social_security_number, Symmetric::Encryption.decrypt(@social_security_number_encrypted)
42
- end
43
-
44
- should "have encrypted methods" do
45
- assert_equal true, @user.respond_to?(:encrypted_bank_account_number)
46
- assert_equal true, @user.respond_to?(:encrypted_social_security_number)
47
- assert_equal false, @user.respond_to?(:encrypted_name)
48
- end
49
-
50
- should "have unencrypted values" do
51
- assert_equal @bank_account_number, @user.bank_account_number
52
- assert_equal @social_security_number, @user.social_security_number
14
+ Symmetric::Encryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
53
15
  end
54
16
 
55
- should "have encrypted values" do
56
- assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
57
- assert_equal @social_security_number_encrypted, @user.encrypted_social_security_number
58
- end
59
-
60
- should "encrypt" do
61
- user = User.new
62
- user.bank_account_number = @bank_account_number
63
- assert_equal @bank_account_number, user.bank_account_number
64
- assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
65
- end
66
-
67
- should "allow lookups using unencrypted or encrypted column name" do
68
- user_id = @user.save!
69
-
70
- inq = User.find_by_bank_account_number(@bank_account_number)
71
- assert_equal @bank_account_number, inq.bank_account_number
72
- assert_equal @bank_account_number_encrypted, inq.encrypted_bank_account_number
73
-
74
- User.delete(user_id)
75
- end
76
-
77
- should "return encrypted attributes for the class" do
78
- expect = {:social_security_number=>:encrypted_social_security_number, :bank_account_number=>:encrypted_bank_account_number, :check_bank_account_number=>:encrypted_check_bank_account_number}
79
- result = User.encrypted_attributes
80
- expect.each_pair {|k,v| assert_equal expect[k], result[k]}
81
- end
17
+ context 'Symmetric::Encryption tests' do
18
+ setup do
19
+ @bank_account_number = "1234567890"
20
+ @bank_account_number_encrypted = "QUxoUU8O/mi0o9ykgXNBFg==\n"
82
21
 
83
- should "return encrypted keys for the class" do
84
- expect = [:social_security_number, :bank_account_number, :check_bank_account_number]
85
- result = User.encrypted_keys
86
- expect.each {|val| assert_equal true, result.include?(val)}
22
+ @social_security_number = "987654321"
23
+ @social_security_number_encrypted = "Jj7dKb3B0aUCnqH/YKGvKw==\n"
24
+ end
87
25
 
88
- # Also check encrypted_attribute?
89
- expect.each {|val| assert_equal true, User.encrypted_attribute?(val)}
90
- end
26
+ should "encrypt simple string" do
27
+ assert_equal @social_security_number_encrypted, Symmetric::Encryption.encrypt(@social_security_number)
28
+ end
91
29
 
92
- should "return encrypted columns for the class" do
93
- expect = [:encrypted_social_security_number, :encrypted_bank_account_number, :encrypted_check_bank_account_number]
94
- result = User.encrypted_columns
95
- expect.each {|val| assert_equal true, result.include?(val)}
30
+ should "decrypt string" do
31
+ assert_equal @social_security_number, Symmetric::Encryption.decrypt(@social_security_number_encrypted)
32
+ end
96
33
 
97
- # Also check encrypted_column?
98
- expect.each {|val| assert_equal true, User.encrypted_column?(val)}
34
+ should "determine if string is encrypted" do
35
+ assert_equal true, Symmetric::Encryption.encrypted?(@social_security_number_encrypted)
36
+ assert_equal false, Symmetric::Encryption.encrypted?(@social_security_number)
37
+ end
99
38
  end
100
-
101
39
  end
40
+
102
41
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
7
  - 2
9
- version: 0.1.2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Reid Morrison
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2012-01-24 00:00:00 -05:00
17
+ date: 2012-03-14 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -28,9 +28,11 @@ extensions: []
28
28
  extra_rdoc_files: []
29
29
 
30
30
  files:
31
+ - examples/symmetric-encryption.yml
31
32
  - lib/symmetric/encryption.rb
32
33
  - lib/symmetric/extensions/active_record/base.rb
33
34
  - lib/symmetric/railtie.rb
35
+ - lib/symmetric/railties/symmetric_encrypted_validator.rb
34
36
  - lib/symmetric/railties/symmetric_encryption.rake
35
37
  - lib/symmetric/version.rb
36
38
  - lib/symmetric-encryption.rb
@@ -43,8 +45,12 @@ files:
43
45
  - nbproject/project.xml
44
46
  - Rakefile
45
47
  - README.md
46
- - symmetric-encryption-0.1.0.gem
47
- - symmetric-encryption-0.1.1.gem
48
+ - symmetric-encryption-0.1.2.gem
49
+ - test/attr_encrypted_test.rb
50
+ - test/config/database.yml
51
+ - test/config/symmetric-encryption.yml
52
+ - test/config/test.iv
53
+ - test/config/test.key
48
54
  - test/encryption_test.rb
49
55
  has_rdoc: true
50
56
  homepage: https://github.com/ClarityServices/symmetric-encryption
Binary file
Binary file