Skip to content
This repository
Browse code

Rename namespace from Symmetric to SymmetricEncryption and Symmetric:…

…:Encryption.encrypt to SymmetricEncryption.encrypt
  • Loading branch information...
commit dc8c016160c0c68c339c82aa650a78163bea2e53 1 parent 2c69eac
Reid Morrison authored April 05, 2012
18  lib/symmetric-encryption.rb
... ...
@@ -1,19 +1,19 @@
1  
-require 'symmetric/version'
2  
-require 'symmetric/cipher'
3  
-require 'symmetric/encryption'
4  
-require 'symmetric/encryption_reader'
5  
-require 'symmetric/encryption_writer'
  1
+require 'symmetric_encryption/version'
  2
+require 'symmetric_encryption/cipher'
  3
+require 'symmetric_encryption/symmetric_encryption'
  4
+require 'symmetric_encryption/reader'
  5
+require 'symmetric_encryption/writer'
6 6
 require 'zlib'
7 7
 if defined?(Rails)
8  
-  require 'symmetric/railtie'
  8
+  require 'symmetric_encryption/railtie'
9 9
 end
10 10
 # attr_encrypted and Encrypted validator
11 11
 if defined?(ActiveRecord::Base)
12  
-  require 'symmetric/extensions/active_record/base'
13  
-  require 'symmetric/railties/symmetric_encrypted_validator'
  12
+  require 'symmetric_encryption/extensions/active_record/base'
  13
+  require 'symmetric_encryption/railties/symmetric_encryption_validator'
14 14
 end
15 15
 
16 16
 # field encryption for Mongoid
17 17
 if defined?(Mongoid)
18  
-  require 'symmetric/extensions/mongoid/fields'
  18
+  require 'symmetric_encryption/extensions/mongoid/fields'
19 19
 end
283  lib/symmetric/encryption.rb
... ...
@@ -1,283 +0,0 @@
1  
-require 'base64'
2  
-require 'openssl'
3  
-require 'zlib'
4  
-require 'yaml'
5  
-
6  
-module Symmetric
7  
-
8  
-  # Encrypt using 256 Bit AES CBC symmetric key and initialization vector
9  
-  # The symmetric key is protected using the private key below and must
10  
-  # be distributed separately from the application
11  
-  class Encryption
12  
-
13  
-    # Defaults
14  
-    @@cipher = nil
15  
-    @@secondary_ciphers = []
16  
-
17  
-    # Set the Primary Symmetric Cipher to be used
18  
-    def self.cipher=(cipher)
19  
-      raise "Cipher must be similar to Symmetric::Ciphers" unless cipher.respond_to?(:encrypt) && cipher.respond_to?(:decrypt)
20  
-      @@cipher = cipher
21  
-    end
22  
-
23  
-    # Returns the Primary Symmetric Cipher being used
24  
-    # If a version is supplied, then the cipher matching that version will be
25  
-    # returned or nil if no match was found
26  
-    def self.cipher(version = nil)
27  
-      return @@cipher if version.nil? || (@@cipher.version == version)
28  
-      secondary_ciphers.find {|c| c.version == version}
29  
-    end
30  
-
31  
-    # Set the Secondary Symmetric Ciphers Array to be used
32  
-    def self.secondary_ciphers=(secondary_ciphers)
33  
-      raise "secondary_ciphers must be a collection" unless secondary_ciphers.respond_to? :each
34  
-      secondary_ciphers.each do |cipher|
35  
-        raise "secondary_ciphers can only consist of Symmetric::Ciphers" unless cipher.respond_to?(:encrypt) && cipher.respond_to?(:decrypt)
36  
-      end
37  
-      @@secondary_ciphers = secondary_ciphers
38  
-    end
39  
-
40  
-    # Returns the Primary Symmetric Cipher being used
41  
-    def self.secondary_ciphers
42  
-      @@secondary_ciphers
43  
-    end
44  
-
45  
-    # AES Symmetric Decryption of supplied string
46  
-    #  Returns decrypted string
47  
-    #  Returns nil if the supplied str is nil
48  
-    #  Returns "" if it is a string and it is empty
49  
-    #
50  
-    # Note: If secondary ciphers are supplied in the configuration file the
51  
-    #   first key will be used to decrypt 'str'. If it fails each cipher in the
52  
-    #   order supplied will be tried.
53  
-    #   It is slow to try each cipher in turn, so should be used during migrations
54  
-    #   only
55  
-    #
56  
-    # Raises: OpenSSL::Cipher::CipherError when 'str' was not encrypted using
57  
-    # the supplied key and iv
58  
-    #
59  
-    def self.decrypt(str)
60  
-      raise "Call Symmetric::Encryption.load! or Symmetric::Encryption.cipher= prior to encrypting or decrypting data" unless @@cipher
61  
-      binary = ::Base64.decode64(str) if str
62  
-      begin
63  
-        @@cipher.decrypt(binary)
64  
-      rescue OpenSSL::Cipher::CipherError => exc
65  
-        @@secondary_ciphers.each do |cipher|
66  
-          begin
67  
-            return cipher.decrypt(binary)
68  
-          rescue OpenSSL::Cipher::CipherError
69  
-          end
70  
-        end
71  
-        raise exc
72  
-      end
73  
-    end
74  
-
75  
-    # AES Symmetric Encryption of supplied string
76  
-    #  Returns result as a Base64 encoded string
77  
-    #  Returns nil if the supplied str is nil
78  
-    #  Returns "" if it is a string and it is empty
79  
-    def self.encrypt(str)
80  
-      raise "Call Symmetric::Encryption.load! or Symmetric::Encryption.cipher= prior to encrypting or decrypting data" unless @@cipher
81  
-
82  
-      # Encrypt data as a binary string
83  
-      result = @@cipher.encrypt(str)
84  
-
85  
-      # Base 64 Encoding of binary data
86  
-      result = ::Base64.encode64(result) if result
87  
-      result
88  
-    end
89  
-
90  
-    # Invokes decrypt
91  
-    #  Returns decrypted String
92  
-    #  Return nil if it fails to decrypt a String
93  
-    #
94  
-    # Useful for example when decoding passwords encrypted using a key from a
95  
-    # different environment. I.e. We cannot decode production passwords
96  
-    # in the test or development environments but still need to be able to load
97  
-    # YAML config files that contain encrypted development and production passwords
98  
-    def self.try_decrypt(str)
99  
-      raise "Call Symmetric::Encryption.load! or Symmetric::Encryption.cipher= prior to encrypting or decrypting data" unless @@cipher
100  
-      begin
101  
-        decrypt(str)
102  
-      rescue OpenSSL::Cipher::CipherError
103  
-        nil
104  
-      end
105  
-    end
106  
-
107  
-    # Returns [true|false] as to whether the data could be decrypted
108  
-    #   Parameters:
109  
-    #     encrypted_data: Encrypted string
110  
-    def self.encrypted?(encrypted_data)
111  
-      raise "Call Symmetric::Encryption.load! or Symmetric::Encryption.cipher= prior to encrypting or decrypting data" unless @@cipher
112  
-
113  
-      # First make sure Base64 encoded data still ends with "\n" since it could be used in a key field somewhere
114  
-      return false unless encrypted_data.end_with?("\n")
115  
-
116  
-      # For now have to decrypt it fully
117  
-      !try_decrypt(encrypted_data).nil?
118  
-    end
119  
-
120  
-    # Load the Encryption Configuration from a YAML file
121  
-    #  filename:
122  
-    #    Name of file to read.
123  
-    #        Mandatory for non-Rails apps
124  
-    #        Default: Rails.root/config/symmetric-encryption.yml
125  
-    #  environment:
126  
-    #    Which environments config to load. Usually: production, development, etc.
127  
-    #    Default: Rails.env
128  
-    def self.load!(filename=nil, environment=nil)
129  
-      config = read_config(filename, environment)
130  
-
131  
-      # Check for hard coded key, iv and cipher
132  
-      if config[:key]
133  
-        @@cipher = Cipher.new(config)
134  
-        @@secondary_ciphers = []
135  
-      else
136  
-        private_rsa_key = config[:private_rsa_key]
137  
-        @@cipher, *@@secondary_ciphers = config[:ciphers].collect do |cipher_conf|
138  
-          cipher_from_encrypted_files(
139  
-            private_rsa_key,
140  
-            cipher_conf[:cipher],
141  
-            cipher_conf[:key_filename],
142  
-            cipher_conf[:iv_filename])
143  
-        end
144  
-      end
145  
-
146  
-      true
147  
-    end
148  
-
149  
-    # Future: Generate private key in config file generator
150  
-    #new_key = OpenSSL::PKey::RSA.generate(2048)
151  
-
152  
-    # Generate new random symmetric keys for use with this Encryption library
153  
-    #
154  
-    # Note: Only the current Encryption key settings are used
155  
-    #
156  
-    # Creates Symmetric Key .key
157  
-    #   and initilization vector .iv
158  
-    #       which is encrypted with the above Public key
159  
-    #
160  
-    # Warning: Existing files will be overwritten
161  
-    def self.generate_symmetric_key_files(filename=nil, environment=nil)
162  
-      config = read_config(filename, environment)
163  
-      cipher_cfg = config[:ciphers].first
164  
-      key_filename = cipher_cfg[:key_filename]
165  
-      iv_filename = cipher_cfg[:iv_filename]
166  
-      cipher = cipher_cfg[:cipher]
167  
-
168  
-      raise "The configuration file must contain a 'private_rsa_key' parameter to generate symmetric keys" unless config[:private_rsa_key]
169  
-      rsa_key = OpenSSL::PKey::RSA.new(config[:private_rsa_key])
170  
-
171  
-      # Generate a new Symmetric Key pair
172  
-      key_pair = Symmetric::Cipher.random_key_pair(cipher || 'aes-256-cbc', !iv_filename.nil?)
173  
-
174  
-      # Save symmetric key after encrypting it with the private RSA key, backing up existing files if present
175  
-      File.rename(key_filename, "#{key_filename}.#{Time.now.to_i}") if File.exist?(key_filename)
176  
-      File.open(key_filename, 'wb') {|file| file.write( rsa_key.public_encrypt(key_pair[:key]) ) }
177  
-
178  
-      if iv_filename
179  
-        File.rename(iv_filename, "#{iv_filename}.#{Time.now.to_i}") if File.exist?(iv_filename)
180  
-        File.open(iv_filename, 'wb') {|file| file.write( rsa_key.public_encrypt(key_pair[:iv]) ) }
181  
-      end
182  
-      puts("Generated new Symmetric Key for encryption. Please copy #{key_filename} and #{iv_filename} to the other web servers in #{environment}.")
183  
-    end
184  
-
185  
-    # Generate a 22 character random password
186  
-    def self.random_password
187  
-      Base64.encode64(OpenSSL::Cipher.new('aes-128-cbc').random_key)[0..-4]
188  
-    end
189  
-
190  
-    # Binary encrypted data includes this magic header so that we can quickly
191  
-    # identify binary data versus base64 encoded data that does not have this header
192  
-    unless defined? MAGIC_HEADER
193  
-      MAGIC_HEADER = '@EnC'
194  
-      MAGIC_HEADER_SIZE = MAGIC_HEADER.size
195  
-      MAGIC_HEADER_UNPACK = "A#{MAGIC_HEADER_SIZE}v"
196  
-    end
197  
-
198  
-    protected
199  
-
200  
-    # Returns the Encryption Configuration
201  
-    #
202  
-    # Read the configuration from the YAML file and return in the latest format
203  
-    #
204  
-    #  filename:
205  
-    #    Name of file to read.
206  
-    #        Mandatory for non-Rails apps
207  
-    #        Default: Rails.root/config/symmetric-encryption.yml
208  
-    #  environment:
209  
-    #    Which environments config to load. Usually: production, development, etc.
210  
-    def self.read_config(filename=nil, environment=nil)
211  
-      config = YAML.load_file(filename || File.join(Rails.root, "config", "symmetric-encryption.yml"))[environment || Rails.env]
212  
-
213  
-      # Default cipher
214  
-      default_cipher = config['cipher'] || 'aes-256-cbc'
215  
-      cfg = {}
216  
-
217  
-      # Hard coded symmetric_key? - Dev / Testing use only!
218  
-      if symmetric_key = (config['key'] || config['symmetric_key'])
219  
-        raise "Symmetric::Encryption Cannot hard code Production encryption keys in #{filename}" if (environment || Rails.env) == 'production'
220  
-        cfg[:key]     = symmetric_key
221  
-        cfg[:iv]      = config['iv'] || config['symmetric_iv']
222  
-        cfg[:cipher]  = default_cipher
223  
-
224  
-      elsif ciphers = config['ciphers']
225  
-        raise "Missing mandatory config parameter 'private_rsa_key'" unless cfg[:private_rsa_key] = config['private_rsa_key']
226  
-
227  
-        cfg[:ciphers] = ciphers.collect do |cipher_cfg|
228  
-          key_filename = cipher_cfg['key_filename'] || cipher_cfg['symmetric_key_filename']
229  
-          raise "Missing mandatory 'key_filename' for environment:#{environment} in #{filename}" unless key_filename
230  
-          iv_filename = cipher_cfg['iv_filename'] || cipher_cfg['symmetric_iv_filename']
231  
-          {
232  
-            :cipher       => cipher_cfg['cipher'] || default_cipher,
233  
-            :key_filename => key_filename,
234  
-            :iv_filename  => iv_filename,
235  
-          }
236  
-        end
237  
-
238  
-      else
239  
-        # Migrate old format config
240  
-        raise "Missing mandatory config parameter 'private_rsa_key'" unless cfg[:private_rsa_key] = config['private_rsa_key']
241  
-        cfg[:ciphers] = [ {
242  
-            :cipher       => default_cipher,
243  
-            :key_filename => config['symmetric_key_filename'],
244  
-            :iv_filename  => config['symmetric_iv_filename'],
245  
-          } ]
246  
-      end
247  
-
248  
-      cfg
249  
-    end
250  
-
251  
-    # Returns an instance of Symmetric::Cipher initialized from keys
252  
-    # stored in files
253  
-    #
254  
-    # Raises an Exception on failure
255  
-    #
256  
-    # Parameters:
257  
-    #   cipher
258  
-    #     Encryption cipher for the symmetric encryption key
259  
-    #   private_key
260  
-    #     Key used to unlock file containing the actual symmetric key
261  
-    #   key_filename
262  
-    #     Name of file containing symmetric key encrypted using the public
263  
-    #     key matching the supplied private_key
264  
-    #   iv_filename
265  
-    #     Optional. Name of file containing symmetric key initialization vector
266  
-    #     encrypted using the public key matching the supplied private_key
267  
-    def self.cipher_from_encrypted_files(private_rsa_key, cipher, key_filename, iv_filename = nil)
268  
-      # Load Encrypted Symmetric keys
269  
-      encrypted_key = File.read(key_filename)
270  
-      encrypted_iv = File.read(iv_filename) if iv_filename
271  
-
272  
-      # Decrypt Symmetric Keys
273  
-      rsa = OpenSSL::PKey::RSA.new(private_rsa_key)
274  
-      iv = rsa.private_decrypt(encrypted_iv) if iv_filename
275  
-      Cipher.new(
276  
-        :key    => rsa.private_decrypt(encrypted_key),
277  
-        :iv     => iv,
278  
-        :cipher => cipher
279  
-      )
280  
-    end
281  
-
282  
-  end
283  
-end
4  lib/symmetric/version.rb
... ...
@@ -1,4 +0,0 @@
1  
-# encoding: utf-8
2  
-module Symmetric #:nodoc
3  
-  VERSION = "0.4.0"
4  
-end
6  lib/symmetric/cipher.rb → lib/symmetric_encryption/cipher.rb
... ...
@@ -1,8 +1,4 @@
1  
-require 'base64'
2  
-require 'openssl'
3  
-require 'zlib'
4  
-
5  
-module Symmetric
  1
+module SymmetricEncryption
6 2
 
7 3
   # Hold all information related to encryption keys
8 4
   # as well as encrypt and decrypt data using those keys
8  lib/symmetric/extensions/active_record/base.rb → ...etric_encryption/extensions/active_record/base.rb
@@ -3,7 +3,7 @@ class Base
3 3
 
4 4
     class << self # Class methods
5 5
       # Much lighter weight encryption for Rails attributes matching the
6  
-      # attr_encrypted interface using Symmetric::Encryption
  6
+      # attr_encrypted interface using SymmetricEncryption
7 7
       #
8 8
       # The regular attr_encrypted gem uses Encryptor that adds encryption to
9 9
       # every Ruby object which is a complete overkill for this simple use-case
@@ -31,7 +31,7 @@ def attr_encrypted(*params)
31 31
             # If this method is not called, then the encrypted value is never decrypted
32 32
             def #{attribute}
33 33
               if @stored_encrypted_#{attribute} != self.encrypted_#{attribute}
34  
-                @#{attribute} = ::Symmetric::Encryption.decrypt(self.encrypted_#{attribute})
  34
+                @#{attribute} = ::SymmetricEncryption.decrypt(self.encrypted_#{attribute})
35 35
                 @stored_encrypted_#{attribute} = self.encrypted_#{attribute}
36 36
               end
37 37
               @#{attribute}
@@ -40,7 +40,7 @@ def #{attribute}
40 40
             # Set the un-encrypted attribute
41 41
             # Also updates the encrypted field with the encrypted value
42 42
             def #{attribute}=(value)
43  
-              self.encrypted_#{attribute} = @stored_encrypted_#{attribute} = ::Symmetric::Encryption.encrypt(value#{".to_yaml" if options[:marshal]})
  43
+              self.encrypted_#{attribute} = @stored_encrypted_#{attribute} = ::SymmetricEncryption.encrypt(value#{".to_yaml" if options[:marshal]})
44 44
               @#{attribute} = value
45 45
             end
46 46
           UNENCRYPTED
@@ -129,7 +129,7 @@ def method_missing_with_attr_encrypted(method, *args, &block)
129 129
           attribute_names.each_with_index do |attribute, index|
130 130
             encrypted_name = "encrypted_#{attribute}"
131 131
             if instance_methods.include? encrypted_name #.to_sym in 1.9
132  
-              args[index] = ::Symmetric::Encryption.encrypt(args[index])
  132
+              args[index] = ::SymmetricEncryption.encrypt(args[index])
133 133
               attribute_names[index] = encrypted_name
134 134
             end
135 135
           end
16  lib/symmetric/extensions/mongoid/fields.rb → ...symmetric_encryption/extensions/mongoid/fields.rb
@@ -16,8 +16,8 @@ module ClassMethods
16 16
       #  Mongoid.logger = Logger.new($stdout)
17 17
       #  Mongoid.load!('config/mongoid.yml')
18 18
       #
19  
-      #  # Initialize Symmetric::Encryption in a standalone environment. In a Rails app this is not required
20  
-      #  Symmetric::Encryption.load!('config/symmetric-encryption.yml', 'test')
  19
+      #  # Initialize SymmetricEncryption in a standalone environment. In a Rails app this is not required
  20
+      #  SymmetricEncryption.load!('config/symmetric-encryption.yml', 'test')
21 21
       #
22 22
       #  class Person
23 23
       #    include Mongoid::Document
@@ -44,13 +44,13 @@ module ClassMethods
44 44
       #   puts "Decrypted Social Security Number is: #{person.social_security_number}"
45 45
       #
46 46
       #   # Or is the same as
47  
-      #   puts "Decrypted Social Security Number is: #{Symmetric::Encryption.decrypt(person.encrypted_social_security_number)}"
  47
+      #   puts "Decrypted Social Security Number is: #{SymmetricEncryption.decrypt(person.encrypted_social_security_number)}"
48 48
       #
49 49
       #   # Sets the encrypted_social_security_number to encrypted version
50 50
       #   person.social_security_number = "123456789"
51 51
       #
52 52
       #   # Or, is equivalent to:
53  
-      #   person.social_security_number = Symmetric::Encryption.encrypt("123456789")
  53
+      #   person.social_security_number = SymmetricEncryption.encrypt("123456789")
54 54
       #
55 55
       #
56 56
       # Note: Unlike attr_encrypted finders must use the encrypted field name
@@ -78,7 +78,7 @@ def field_with_symmetric_encryption(field_name, options={})
78 78
         if options.delete(:encrypted) == true
79 79
           decrypt_as = options.delete(:decrypt_as)
80 80
           unless decrypt_as
81  
-            raise "Symmetric::Encryption for Mongoid. When encryption is enabled for a field it must either start with 'encrypted_' or the option :decrypt must be supplied" unless field_name.to_s.start_with?('encrypted_')
  81
+            raise "SymmetricEncryption for Mongoid. When encryption is enabled for a field it must either start with 'encrypted_' or the option :decrypt must be supplied" unless field_name.to_s.start_with?('encrypted_')
82 82
             decrypt_as = field_name.to_s['encrypted_'.length..-1]
83 83
           end
84 84
 
@@ -86,7 +86,7 @@ def field_with_symmetric_encryption(field_name, options={})
86 86
           underlying_type = options[:type]
87 87
           options[:type] = String
88 88
 
89  
-          raise "Symmetric::Encryption for Mongoid currently only supports :type => String" unless underlying_type == String
  89
+          raise "SymmetricEncryption for Mongoid currently only supports :type => String" unless underlying_type == String
90 90
 
91 91
           # #TODO Need to do type conversions. Currently only support String
92 92
 
@@ -95,7 +95,7 @@ def field_with_symmetric_encryption(field_name, options={})
95 95
             # Set the un-encrypted bank account number
96 96
             # Also updates the encrypted field with the encrypted value
97 97
             def #{decrypt_as}=(value)
98  
-              @stored_#{field_name} = Symmetric::Encryption.encrypt(value)
  98
+              @stored_#{field_name} = SymmetricEncryption.encrypt(value)
99 99
               self.#{field_name} = @stored_#{field_name}
100 100
               @#{decrypt_as} = value
101 101
             end
@@ -105,7 +105,7 @@ def #{decrypt_as}=(value)
105 105
             # If this method is not called, then the encrypted value is never decrypted
106 106
             def #{decrypt_as}
107 107
               if @stored_#{field_name} != self.#{field_name}
108  
-                @#{decrypt_as} = Symmetric::Encryption.decrypt(self.#{field_name})
  108
+                @#{decrypt_as} = SymmetricEncryption.decrypt(self.#{field_name})
109 109
                 @stored_#{field_name} = self.#{field_name}
110 110
               end
111 111
               @#{decrypt_as}
4  lib/symmetric/railtie.rb → lib/symmetric_encryption/railtie.rb
... ...
@@ -1,5 +1,5 @@
1 1
 # encoding: utf-8
2  
-module Symmetric #:nodoc:
  2
+module SymmetricEncryption #:nodoc:
3 3
   class Railtie < Rails::Railtie #:nodoc:
4 4
 
5 5
     # Exposes Symmetric Encryption's configuration to the Rails application configuration.
@@ -31,7 +31,7 @@ class Railtie < Rails::Railtie #:nodoc:
31 31
     initializer "symmetric-encryption.initialize" , :before=>"active_record.initialize_database" do
32 32
       config_file = Rails.root.join("config", "symmetric-encryption.yml")
33 33
       if config_file.file?
34  
-        ::Symmetric::Encryption.load!(config_file, Rails.env)
  34
+        ::SymmetricEncryption.load!(config_file, Rails.env)
35 35
       else
36 36
         puts "\nSymmetric Encryption config not found. Create a config file at: config/symmetric-encryption.yml"
37 37
         #           puts "to generate one run: rails generate symmetric-encryption:config\n\n"
10  lib/symmetric/railties/symmetric_encryption.rake → ...ric_encryption/railties/symmetric_encryption.rake
@@ -3,7 +3,7 @@ namespace :symmetric_encryption do
3 3
   desc 'Decrypt the supplied string. Example: VALUE="_encrypted_string_" rake symmetric_encryption:decrypt'
4 4
   task :decrypt => :environment do
5 5
     puts "\nEncrypted: #{ENV['VALUE']}"
6  
-    puts "Decrypted: #{Symmetric::Encryption.decrypt(ENV['VALUE'])}\n\n"
  6
+    puts "Decrypted: #{SymmetricEncryption.decrypt(ENV['VALUE'])}\n\n"
7 7
   end
8 8
 
9 9
   desc 'Encrypt a value, such as a password. Example: rake symmetric_encryption:encrypt'
@@ -20,19 +20,19 @@ namespace :symmetric_encryption do
20 20
         puts "Passwords do not match, please try again"
21 21
       end
22 22
     end
23  
-    puts "\nEncrypted: #{Symmetric::Encryption.encrypt(password1)}\n\n"
  23
+    puts "\nEncrypted: #{SymmetricEncryption.encrypt(password1)}\n\n"
24 24
   end
25 25
 
26 26
   desc 'Generate new Symmetric key and initialization vector. Example: RAILS_ENV=production rake symmetric_encryption:generate_symmetric_keys'
27 27
   task :generate_symmetric_keys do
28  
-    Symmetric::Encryption.generate_symmetric_key_files
  28
+    SymmetricEncryption.generate_symmetric_key_files
29 29
   end
30 30
 
31 31
   desc 'Generate a random password and display its encrypted form. Example: rake symmetric_encryption:random_password'
32 32
   task :random_password => :environment do
33  
-    p = Symmetric::Encryption.random_password
  33
+    p = SymmetricEncryption.random_password
34 34
     puts "\nGenerated Password: #{p}"
35  
-    puts "Encrypted: #{Symmetric::Encryption.encrypt(p)}\n\n"
  35
+    puts "Encrypted: #{SymmetricEncryption.encrypt(p)}\n\n"
36 36
   end
37 37
 
38 38
 end
8  ...mmetric/railties/symmetric_encrypted_validator.rb → ...yption/railties/symmetric_encryption_validator.rb
@@ -2,17 +2,17 @@
2 2
 #
3 3
 # Example:
4 4
 #  class MyModel < ActiveRecord::Base
5  
-#    validates :encrypted_ssn, :symmetric_encrypted => true
  5
+#    validates :encrypted_ssn, :symmetric_encryption => true
6 6
 #  end
7 7
 #
8 8
 #  m = MyModel.new
9 9
 #  m.valid?
10 10
 #  #  => false
11  
-#  m.encrypted_ssn = Symmetric::Encryption.encrypt('123456789')
  11
+#  m.encrypted_ssn = SymmetricEncryption.encrypt('123456789')
12 12
 #  m.valid?
13 13
 #  #  => true
14  
-class SymmetricEncryptedValidator < ActiveModel::EachValidator
  14
+class SymmetricEncryptionValidator < ActiveModel::EachValidator
15 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)
  16
+    record.errors.add(attribute, "must be a value encrypted using SymmetricEncryption.encrypt") unless SymmetricEncryption.encrypted?(value)
17 17
   end
18 18
 end
81  lib/symmetric/encryption_reader.rb → lib/symmetric_encryption/reader.rb
... ...
@@ -1,40 +1,38 @@
1  
-module Symmetric
2  
-  class EncryptionReader
3  
-    # Read from encrypted files and other IO streams
4  
-    #
5  
-    # Features:
6  
-    # * Decryption on the fly whilst reading files
7  
-    # * Large file support by only buffering small amounts of data in memory
8  
-    #
9  
-    # # Example: Read and decrypt a line at a time from a file
10  
-    # Symmetric::EncryptionReader.open('test_file') do |file|
11  
-    #   file.each_line {|line| p line }
12  
-    # end
13  
-    #
14  
-    # # Example: Read and decrypt entire file in memory
15  
-    # # Not recommended for large files
16  
-    # Symmetric::EncryptionReader.open('test_file') {|f| f.read }
17  
-    #
18  
-    # # Example: Reading a limited number of bytes at a time from the file
19  
-    # Symmetric::EncryptionReader.open('test_file') do |file|
20  
-    #   file.read(1)
21  
-    #   file.read(5)
22  
-    #   file.read
23  
-    # end
24  
-    #
25  
-    # # Example: Read and decrypt 5 bytes at a time until the end of file is reached
26  
-    # Symmetric::EncryptionReader.open('test_file') do |file|
27  
-    #   while !file.eof? do
28  
-    #     file.read(5)
29  
-    #   end
30  
-    # end
31  
-    #
32  
-    # # Example: Read, Unencrypt and decompress data in a file
33  
-    # Symmetric::EncryptionReader.open('encrypted_compressed.zip', :compress => true) do |file|
34  
-    #   file.each_line {|line| p line }
35  
-    # end
36  
-
37  
-
  1
+module SymmetricEncryption
  2
+  # Read from encrypted files and other IO streams
  3
+  #
  4
+  # Features:
  5
+  # * Decryption on the fly whilst reading files
  6
+  # * Large file support by only buffering small amounts of data in memory
  7
+  #
  8
+  # # Example: Read and decrypt a line at a time from a file
  9
+  # SymmetricEncryption::Reader.open('test_file') do |file|
  10
+  #   file.each_line {|line| p line }
  11
+  # end
  12
+  #
  13
+  # # Example: Read and decrypt entire file in memory
  14
+  # # Not recommended for large files
  15
+  # SymmetricEncryption::Reader.open('test_file') {|f| f.read }
  16
+  #
  17
+  # # Example: Reading a limited number of bytes at a time from the file
  18
+  # SymmetricEncryption::Reader.open('test_file') do |file|
  19
+  #   file.read(1)
  20
+  #   file.read(5)
  21
+  #   file.read
  22
+  # end
  23
+  #
  24
+  # # Example: Read and decrypt 5 bytes at a time until the end of file is reached
  25
+  # SymmetricEncryption::Reader.open('test_file') do |file|
  26
+  #   while !file.eof? do
  27
+  #     file.read(5)
  28
+  #   end
  29
+  # end
  30
+  #
  31
+  # # Example: Read, Unencrypt and decompress data in a file
  32
+  # SymmetricEncryption::Reader.open('encrypted_compressed.zip', :compress => true) do |file|
  33
+  #   file.each_line {|line| p line }
  34
+  # end
  35
+  class Reader
38 36
     # Open a file for reading, or use the supplied IO Stream
39 37
     #
40 38
     # Parameters:
@@ -64,7 +62,6 @@ class EncryptionReader
64 62
     #          Default: 4096
65 63
     #
66 64
     # Note: Decryption occurs before decompression
67  
-    #
68 65
     def self.open(filename_or_stream, options={}, &block)
69 66
       raise "options must be a hash" unless options.respond_to?(:each_pair)
70 67
       mode = options.fetch(:mode, 'r')
@@ -89,7 +86,7 @@ def initialize(ios,options={})
89 86
 
90 87
       # Read first block and check for the header
91 88
       buf = @ios.read(@buffer_size)
92  
-      if buf.start_with?(Symmetric::Encryption::MAGIC_HEADER)
  89
+      if buf.start_with?(SymmetricEncryption::MAGIC_HEADER)
93 90
         # Header includes magic header and version byte
94 91
         # Remove header and extract flags
95 92
         header, flags = buf.slice!(0..MAGIC_HEADER_SIZE).unpack(MAGIC_HEADER_UNPACK)
@@ -100,8 +97,8 @@ def initialize(ios,options={})
100 97
       end
101 98
 
102 99
       # Use primary cipher by default, but allow a secondary cipher to be selected for encryption
103  
-      @cipher = Encryption.cipher(@version)
104  
-      raise "Cipher with version:#{@version} not found in any of the configured Symmetric::Encryption ciphers" unless @cipher
  100
+      @cipher = SymmetricEncryption.cipher(@version)
  101
+      raise "Cipher with version:#{@version} not found in any of the configured SymmetricEncryption ciphers" unless @cipher
105 102
       @stream_cipher = @cipher.send(:openssl_cipher, :decrypt)
106 103
 
107 104
       # First call to #update should return an empty string anyway
@@ -119,7 +116,7 @@ def initialize(ios,options={})
119 116
     # Returns nil when the header is not present in the stream
120 117
     #
121 118
     # Note: The file will not be decompressed automatically when compressed.
122  
-    #       To decompress the data automatically call Symmetric::Encryption.open
  119
+    #       To decompress the data automatically call SymmetricEncryption.open
123 120
     def compressed?
124 121
       @compressed
125 122
     end
280  lib/symmetric_encryption/symmetric_encryption.rb
... ...
@@ -0,0 +1,280 @@
  1
+require 'base64'
  2
+require 'openssl'
  3
+require 'zlib'
  4
+require 'yaml'
  5
+
  6
+# Encrypt using 256 Bit AES CBC symmetric key and initialization vector
  7
+# The symmetric key is protected using the private key below and must
  8
+# be distributed separately from the application
  9
+module SymmetricEncryption
  10
+
  11
+  # Defaults
  12
+  @@cipher = nil
  13
+  @@secondary_ciphers = []
  14
+
  15
+  # Set the Primary Symmetric Cipher to be used
  16
+  def self.cipher=(cipher)
  17
+    raise "Cipher must be similar to SymmetricEncryption::Ciphers" unless cipher.respond_to?(:encrypt) && cipher.respond_to?(:decrypt)
  18
+    @@cipher = cipher
  19
+  end
  20
+
  21
+  # Returns the Primary Symmetric Cipher being used
  22
+  # If a version is supplied, then the cipher matching that version will be
  23
+  # returned or nil if no match was found
  24
+  def self.cipher(version = nil)
  25
+    return @@cipher if version.nil? || (@@cipher.version == version)
  26
+    secondary_ciphers.find {|c| c.version == version}
  27
+  end
  28
+
  29
+  # Set the Secondary Symmetric Ciphers Array to be used
  30
+  def self.secondary_ciphers=(secondary_ciphers)
  31
+    raise "secondary_ciphers must be a collection" unless secondary_ciphers.respond_to? :each
  32
+    secondary_ciphers.each do |cipher|
  33
+      raise "secondary_ciphers can only consist of SymmetricEncryption::Ciphers" unless cipher.respond_to?(:encrypt) && cipher.respond_to?(:decrypt)
  34
+    end
  35
+    @@secondary_ciphers = secondary_ciphers
  36
+  end
  37
+
  38
+  # Returns the Primary Symmetric Cipher being used
  39
+  def self.secondary_ciphers
  40
+    @@secondary_ciphers
  41
+  end
  42
+
  43
+  # AES Symmetric Decryption of supplied string
  44
+  #  Returns decrypted string
  45
+  #  Returns nil if the supplied str is nil
  46
+  #  Returns "" if it is a string and it is empty
  47
+  #
  48
+  # Note: If secondary ciphers are supplied in the configuration file the
  49
+  #   first key will be used to decrypt 'str'. If it fails each cipher in the
  50
+  #   order supplied will be tried.
  51
+  #   It is slow to try each cipher in turn, so should be used during migrations
  52
+  #   only
  53
+  #
  54
+  # Raises: OpenSSL::Cipher::CipherError when 'str' was not encrypted using
  55
+  # the supplied key and iv
  56
+  #
  57
+  def self.decrypt(str)
  58
+    raise "Call SymmetricEncryption.load! or SymmetricEncryption.cipher= prior to encrypting or decrypting data" unless @@cipher
  59
+    binary = ::Base64.decode64(str) if str
  60
+    begin
  61
+      @@cipher.decrypt(binary)
  62
+    rescue OpenSSL::Cipher::CipherError => exc
  63
+      @@secondary_ciphers.each do |cipher|
  64
+        begin
  65
+          return cipher.decrypt(binary)
  66
+        rescue OpenSSL::Cipher::CipherError
  67
+        end
  68
+      end
  69
+      raise exc
  70
+    end
  71
+  end
  72
+
  73
+  # AES Symmetric Encryption of supplied string
  74
+  #  Returns result as a Base64 encoded string
  75
+  #  Returns nil if the supplied str is nil
  76
+  #  Returns "" if it is a string and it is empty
  77
+  def self.encrypt(str)
  78
+    raise "Call SymmetricEncryption.load! or SymmetricEncryption.cipher= prior to encrypting or decrypting data" unless @@cipher
  79
+
  80
+    # Encrypt data as a binary string
  81
+    result = @@cipher.encrypt(str)
  82
+
  83
+    # Base 64 Encoding of binary data
  84
+    result = ::Base64.encode64(result) if result
  85
+    result
  86
+  end
  87
+
  88
+  # Invokes decrypt
  89
+  #  Returns decrypted String
  90
+  #  Return nil if it fails to decrypt a String
  91
+  #
  92
+  # Useful for example when decoding passwords encrypted using a key from a
  93
+  # different environment. I.e. We cannot decode production passwords
  94
+  # in the test or development environments but still need to be able to load
  95
+  # YAML config files that contain encrypted development and production passwords
  96
+  def self.try_decrypt(str)
  97
+    raise "Call SymmetricEncryption.load! or SymmetricEncryption.cipher= prior to encrypting or decrypting data" unless @@cipher
  98
+    begin
  99
+      decrypt(str)
  100
+    rescue OpenSSL::Cipher::CipherError
  101
+      nil
  102
+    end
  103
+  end
  104
+
  105
+  # Returns [true|false] as to whether the data could be decrypted
  106
+  #   Parameters:
  107
+  #     encrypted_data: Encrypted string
  108
+  def self.encrypted?(encrypted_data)
  109
+    raise "Call SymmetricEncryption.load! or SymmetricEncryption.cipher= prior to encrypting or decrypting data" unless @@cipher
  110
+
  111
+    # First make sure Base64 encoded data still ends with "\n" since it could be used in a key field somewhere
  112
+    return false unless encrypted_data.end_with?("\n")
  113
+
  114
+    # For now have to decrypt it fully
  115
+    !try_decrypt(encrypted_data).nil?
  116
+  end
  117
+
  118
+  # Load the Encryption Configuration from a YAML file
  119
+  #  filename:
  120
+  #    Name of file to read.
  121
+  #        Mandatory for non-Rails apps
  122
+  #        Default: Rails.root/config/symmetric-encryption.yml
  123
+  #  environment:
  124
+  #    Which environments config to load. Usually: production, development, etc.
  125
+  #    Default: Rails.env
  126
+  def self.load!(filename=nil, environment=nil)
  127
+    config = read_config(filename, environment)
  128
+
  129
+    # Check for hard coded key, iv and cipher
  130
+    if config[:key]
  131
+      @@cipher = Cipher.new(config)
  132
+      @@secondary_ciphers = []
  133
+    else
  134
+      private_rsa_key = config[:private_rsa_key]
  135
+      @@cipher, *@@secondary_ciphers = config[:ciphers].collect do |cipher_conf|
  136
+        cipher_from_encrypted_files(
  137
+          private_rsa_key,
  138
+          cipher_conf[:cipher],
  139
+          cipher_conf[:key_filename],
  140
+          cipher_conf[:iv_filename])
  141
+      end
  142
+    end
  143
+
  144
+    true
  145
+  end
  146
+
  147
+  # Future: Generate private key in config file generator
  148
+  #new_key = OpenSSL::PKey::RSA.generate(2048)
  149
+
  150
+  # Generate new random symmetric keys for use with this Encryption library
  151
+  #
  152
+  # Note: Only the current Encryption key settings are used
  153
+  #
  154
+  # Creates Symmetric Key .key
  155
+  #   and initilization vector .iv
  156
+  #       which is encrypted with the above Public key
  157
+  #
  158
+  # Warning: Existing files will be overwritten
  159
+  def self.generate_symmetric_key_files(filename=nil, environment=nil)
  160
+    config = read_config(filename, environment)
  161
+    cipher_cfg = config[:ciphers].first
  162
+    key_filename = cipher_cfg[:key_filename]
  163
+    iv_filename = cipher_cfg[:iv_filename]
  164
+    cipher = cipher_cfg[:cipher]
  165
+
  166
+    raise "The configuration file must contain a 'private_rsa_key' parameter to generate symmetric keys" unless config[:private_rsa_key]
  167
+    rsa_key = OpenSSL::PKey::RSA.new(config[:private_rsa_key])
  168
+
  169
+    # Generate a new Symmetric Key pair
  170
+    key_pair = SymmetricEncryption::Cipher.random_key_pair(cipher || 'aes-256-cbc', !iv_filename.nil?)
  171
+
  172
+    # Save symmetric key after encrypting it with the private RSA key, backing up existing files if present
  173
+    File.rename(key_filename, "#{key_filename}.#{Time.now.to_i}") if File.exist?(key_filename)
  174
+    File.open(key_filename, 'wb') {|file| file.write( rsa_key.public_encrypt(key_pair[:key]) ) }
  175
+
  176
+    if iv_filename
  177
+      File.rename(iv_filename, "#{iv_filename}.#{Time.now.to_i}") if File.exist?(iv_filename)
  178
+      File.open(iv_filename, 'wb') {|file| file.write( rsa_key.public_encrypt(key_pair[:iv]) ) }
  179
+    end
  180
+    puts("Generated new Symmetric Key for encryption. Please copy #{key_filename} and #{iv_filename} to the other web servers in #{environment}.")
  181
+  end
  182
+
  183
+  # Generate a 22 character random password
  184
+  def self.random_password
  185
+    Base64.encode64(OpenSSL::Cipher.new('aes-128-cbc').random_key)[0..-4]
  186
+  end
  187
+
  188
+  # Binary encrypted data includes this magic header so that we can quickly
  189
+  # identify binary data versus base64 encoded data that does not have this header
  190
+  unless defined? MAGIC_HEADER
  191
+    MAGIC_HEADER = '@EnC'
  192
+    MAGIC_HEADER_SIZE = MAGIC_HEADER.size
  193
+    MAGIC_HEADER_UNPACK = "A#{MAGIC_HEADER_SIZE}v"
  194
+  end
  195
+
  196
+  protected
  197
+
  198
+  # Returns the Encryption Configuration
  199
+  #
  200
+  # Read the configuration from the YAML file and return in the latest format
  201
+  #
  202
+  #  filename:
  203
+  #    Name of file to read.
  204
+  #        Mandatory for non-Rails apps
  205
+  #        Default: Rails.root/config/symmetric-encryption.yml
  206
+  #  environment:
  207
+  #    Which environments config to load. Usually: production, development, etc.
  208
+  def self.read_config(filename=nil, environment=nil)
  209
+    config = YAML.load_file(filename || File.join(Rails.root, "config", "symmetric-encryption.yml"))[environment || Rails.env]
  210
+
  211
+    # Default cipher
  212
+    default_cipher = config['cipher'] || 'aes-256-cbc'
  213
+    cfg = {}
  214
+
  215
+    # Hard coded symmetric_key? - Dev / Testing use only!
  216
+    if symmetric_key = (config['key'] || config['symmetric_key'])
  217
+      raise "SymmetricEncryption Cannot hard code Production encryption keys in #{filename}" if (environment || Rails.env) == 'production'
  218
+      cfg[:key]     = symmetric_key
  219
+      cfg[:iv]      = config['iv'] || config['symmetric_iv']
  220
+      cfg[:cipher]  = default_cipher
  221
+
  222
+    elsif ciphers = config['ciphers']
  223
+      raise "Missing mandatory config parameter 'private_rsa_key'" unless cfg[:private_rsa_key] = config['private_rsa_key']
  224
+
  225
+      cfg[:ciphers] = ciphers.collect do |cipher_cfg|
  226
+        key_filename = cipher_cfg['key_filename'] || cipher_cfg['symmetric_key_filename']
  227
+        raise "Missing mandatory 'key_filename' for environment:#{environment} in #{filename}" unless key_filename
  228
+        iv_filename = cipher_cfg['iv_filename'] || cipher_cfg['symmetric_iv_filename']
  229
+        {
  230
+          :cipher       => cipher_cfg['cipher'] || default_cipher,
  231
+          :key_filename => key_filename,
  232
+          :iv_filename  => iv_filename,
  233
+        }
  234
+      end
  235
+
  236
+    else
  237
+      # Migrate old format config
  238
+      raise "Missing mandatory config parameter 'private_rsa_key'" unless cfg[:private_rsa_key] = config['private_rsa_key']
  239
+      cfg[:ciphers] = [ {
  240
+          :cipher       => default_cipher,
  241
+          :key_filename => config['symmetric_key_filename'],
  242
+          :iv_filename  => config['symmetric_iv_filename'],
  243
+        } ]
  244
+    end
  245
+
  246
+    cfg
  247
+  end
  248
+
  249
+  # Returns an instance of SymmetricEncryption::Cipher initialized from keys
  250
+  # stored in files
  251
+  #
  252
+  # Raises an Exception on failure
  253
+  #
  254
+  # Parameters:
  255
+  #   cipher
  256
+  #     Encryption cipher for the symmetric encryption key
  257
+  #   private_key
  258
+  #     Key used to unlock file containing the actual symmetric key
  259
+  #   key_filename
  260
+  #     Name of file containing symmetric key encrypted using the public
  261
+  #     key matching the supplied private_key
  262
+  #   iv_filename
  263
+  #     Optional. Name of file containing symmetric key initialization vector
  264
+  #     encrypted using the public key matching the supplied private_key
  265
+  def self.cipher_from_encrypted_files(private_rsa_key, cipher, key_filename, iv_filename = nil)
  266
+    # Load Encrypted Symmetric keys
  267
+    encrypted_key = File.read(key_filename)
  268
+    encrypted_iv = File.read(iv_filename) if iv_filename
  269
+
  270
+    # Decrypt Symmetric Keys
  271
+    rsa = OpenSSL::PKey::RSA.new(private_rsa_key)
  272
+    iv = rsa.private_decrypt(encrypted_iv) if iv_filename
  273
+    Cipher.new(
  274
+      :key    => rsa.private_decrypt(encrypted_key),
  275
+      :iv     => iv,
  276
+      :cipher => cipher
  277
+    )
  278
+  end
  279
+
  280
+end
4  lib/symmetric_encryption/version.rb
... ...
@@ -0,0 +1,4 @@
  1
+# encoding: utf-8
  2
+module SymmetricEncryption #:nodoc
  3
+  VERSION = "0.5.0"
  4
+end
12  lib/symmetric/encryption_writer.rb → lib/symmetric_encryption/writer.rb
... ...
@@ -1,5 +1,5 @@
1  
-module Symmetric
2  
-  class EncryptionWriter
  1
+module SymmetricEncryption
  2
+  class Writer
3 3
     # Write to encrypted files and other IO streams
4 4
     #
5 5
     # Features:
@@ -10,13 +10,13 @@ class EncryptionWriter
10 10
     #   Only the last block in the file will be padded if it is less than the block size
11 11
     #
12 12
     # # Example: Encrypt and write data to a file
13  
-    # Symmetric::EncryptionWriter.open('test_file') do |file|
  13
+    # SymmetricEncryption::Writer.open('test_file') do |file|
14 14
     #   file.write "Hello World\n"
15 15
     #   file.write "Keep this secret"
16 16
     # end
17 17
     #
18 18
     # # Example: Compress, Encrypt and write data to a file
19  
-    # Symmetric::EncryptionWriter.open('encrypted_compressed.zip', :compress => true) do |file|
  19
+    # SymmetricEncryption::Writer.open('encrypted_compressed.zip', :compress => true) do |file|
20 20
     #   file.write "Hello World\n"
21 21
     #   file.write "Compress this\n"
22 22
     #   file.write "Keep this safe and secure\n"
@@ -80,8 +80,8 @@ def initialize(ios,options={})
80 80
       @compress = options.fetch(:compress, false)
81 81
 
82 82
       # Use primary cipher by default, but allow a secondary cipher to be selected for encryption
83  
-      @cipher   = Encryption.cipher(options[:version])
84  
-      raise "Cipher with version:#{options[:version]} not found in any of the configured Symmetric::Encryption ciphers" unless @cipher
  83
+      @cipher   = SymmetricEncryption.cipher(options[:version])
  84
+      raise "Cipher with version:#{options[:version]} not found in any of the configured SymmetricEncryption ciphers" unless @cipher
85 85
 
86 86
       @stream_cipher = @cipher.send(:openssl_cipher, :encrypt)
87 87
 
14  test/attr_encrypted_test.rb
@@ -27,12 +27,12 @@ class User < ActiveRecord::Base
27 27
   attr_encrypted :bank_account_number
28 28
   attr_encrypted :social_security_number
29 29
 
30  
-  validates :encrypted_bank_account_number, :symmetric_encrypted => true
31  
-  validates :encrypted_social_security_number, :symmetric_encrypted => true
  30
+  validates :encrypted_bank_account_number, :symmetric_encryption => true
  31
+  validates :encrypted_social_security_number, :symmetric_encryption => true
32 32
 end
33 33
 
34 34
 # Load Symmetric Encryption keys
35  
-Symmetric::Encryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
  35
+SymmetricEncryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
36 36
 
37 37
 # Initialize the database connection
38 38
 config_file = File.join(File.dirname(__FILE__), 'config', 'database.yml')
@@ -44,10 +44,10 @@ class User < ActiveRecord::Base
44 44
 User.establish_connection(cfg)
45 45
 
46 46
 #
47  
-# Unit Test for attr_encrypted and validation aspects of Symmetric::Encryption
  47
+# Unit Test for attr_encrypted and validation aspects of SymmetricEncryption
48 48
 #
49 49
 class AttrEncryptedTest < Test::Unit::TestCase
50  
-  context 'the Symmetric::Encryption Library' do
  50
+  context 'the SymmetricEncryption Library' do
51 51
 
52 52
     setup do
53 53
       @bank_account_number = "1234567890"
@@ -159,8 +159,8 @@ class AttrEncryptedTest < Test::Unit::TestCase
159 159
       assert_equal true, @user.valid?
160 160
       @user.encrypted_bank_account_number = '123'
161 161
       assert_equal false, @user.valid?
162  
-      assert_equal ["must be a value encrypted using Symmetric::Encryption.encrypt"], @user.errors[:encrypted_bank_account_number]
163  
-      @user.encrypted_bank_account_number = Symmetric::Encryption.encrypt('123')
  162
+      assert_equal ["must be a value encrypted using SymmetricEncryption.encrypt"], @user.errors[:encrypted_bank_account_number]
  163
+      @user.encrypted_bank_account_number = SymmetricEncryption.encrypt('123')
164 164
       assert_equal true, @user.valid?
165 165
       @user.bank_account_number = '123'
166 166
       assert_equal true, @user.valid?
12  test/cipher_test.rb
@@ -4,15 +4,15 @@
4 4
 require 'rubygems'
5 5
 require 'test/unit'
6 6
 require 'shoulda'
7  
-require 'symmetric/cipher'
  7
+require 'symmetric_encryption/cipher'
8 8
 
9  
-# Unit Test for Symmetric::Cipher
  9
+# Unit Test for SymmetricEncryption::Cipher
10 10
 #
11 11
 class CipherTest < Test::Unit::TestCase
12 12
   context 'standalone' do
13 13
 
14 14
     should "allow setting the cipher" do
15  
-      cipher = Symmetric::Cipher.new(
  15
+      cipher = SymmetricEncryption::Cipher.new(
16 16
         :cipher => 'aes-128-cbc',
17 17
         :key => '1234567890ABCDEF1234567890ABCDEF',
18 18
         :iv  => '1234567890ABCDEF'
@@ -21,14 +21,14 @@ class CipherTest < Test::Unit::TestCase
21 21
     end
22 22
 
23 23
     should "not require an iv" do
24  
-      cipher = Symmetric::Cipher.new(
  24
+      cipher = SymmetricEncryption::Cipher.new(
25 25
         :key => '1234567890ABCDEF1234567890ABCDEF'
26 26
       )
27 27
       assert_equal "\302<\351\227oj\372\3331\310\260V\001\v'\346", cipher.encrypt('Hello World')
28 28
     end
29 29
 
30 30
     should "throw an exception on bad data" do
31  
-      cipher = Symmetric::Cipher.new(
  31
+      cipher = SymmetricEncryption::Cipher.new(
32 32
         :cipher => 'aes-128-cbc',
33 33
         :key => '1234567890ABCDEF1234567890ABCDEF',
34 34
         :iv  => '1234567890ABCDEF'
@@ -42,7 +42,7 @@ class CipherTest < Test::Unit::TestCase
42 42
 
43 43
   context 'with configuration' do
44 44
     setup do
45  
-      @cipher = Symmetric::Cipher.new(
  45
+      @cipher = SymmetricEncryption::Cipher.new(
46 46
         :key => '1234567890ABCDEF1234567890ABCDEF',
47 47
         :iv  => '1234567890ABCDEF'
48 48
       )
52  test/encryption_test.rb
... ...
@@ -1,52 +0,0 @@
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 'test/unit'
6  
-require 'shoulda'
7  
-require 'symmetric-encryption'
8  
-
9  
-Symmetric::Encryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
10  
-
11  
-# Unit Test for Symmetric::Encryption
12  
-#
13  
-class EncryptionTest < Test::Unit::TestCase
14  
-  context 'initialized' do
15  
-
16  
-    context 'Symmetric::Encryption configuration' do
17  
-      setup do
18  
-        @config = Symmetric::Encryption.send(:read_config, File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
19  
-      end
20  
-
21  
-      should "match config file" do
22  
-        assert_equal @config[:ciphers][0][:cipher], Symmetric::Encryption.cipher.cipher
23  
-      end
24  
-    end
25  
-
26  
-    context 'Symmetric::Encryption tests' do
27  
-      setup do
28  
-        @social_security_number = "987654321"
29  
-        @social_security_number_encrypted = "S+8X1NRrqdfEIQyFHVPuVA==\n"
30  
-        @social_security_number_encrypted_with_secondary_1 = "D1UCu38pqJ3jc0GvwJHiow==\n"
31  
-      end
32  
-
33  
-      should "encrypt simple string" do
34  
-        assert_equal @social_security_number_encrypted, Symmetric::Encryption.encrypt(@social_security_number)
35  
-      end
36  
-
37  
-      should "decrypt string" do
38