lib/symmetric_encryption/symmetric_encryption.rb in symmetric-encryption-4.2.1 vs lib/symmetric_encryption/symmetric_encryption.rb in symmetric-encryption-4.3.0

- old
+ new

@@ -6,15 +6,10 @@ # Encrypt using 256 Bit AES CBC symmetric key and initialization vector # The symmetric key is protected using the private key below and must # be distributed separately from the application module SymmetricEncryption - # Defaults - @@cipher = nil - @@secondary_ciphers = [] - @@select_cipher = nil - # List of types supported when encrypting or decrypting data # # Each type maps to the built-in Ruby types as follows: # :string => String # :integer => Integer @@ -37,11 +32,11 @@ # cipher: 'aes-128-cbc' # ) def self.cipher=(cipher) raise(ArgumentError, 'Cipher must respond to :encrypt and :decrypt') unless cipher.nil? || (cipher.respond_to?(:encrypt) && cipher.respond_to?(:decrypt)) - @@cipher = cipher + @cipher = cipher end # Returns the Primary Symmetric Cipher being used # If a version is supplied # Returns the primary cipher if no match was found and version == 0 @@ -52,35 +47,46 @@ SymmetricEncryption::ConfigError, 'Call SymmetricEncryption.load! or SymmetricEncryption.cipher= prior to encrypting or decrypting data' ) end - return @@cipher if version.nil? || (@@cipher.version == version) + return @cipher if version.nil? || (@cipher.version == version) - secondary_ciphers.find { |c| c.version == version } || (@@cipher if version.zero?) + secondary_ciphers.find { |c| c.version == version } || (@cipher if version.zero?) end # Returns whether a primary cipher has been set def self.cipher? - !@@cipher.nil? + !@cipher.nil? end # Set the Secondary Symmetric Ciphers Array to be used def self.secondary_ciphers=(secondary_ciphers) raise(ArgumentError, 'secondary_ciphers must be a collection') unless secondary_ciphers.respond_to? :each secondary_ciphers.each do |cipher| raise(ArgumentError, 'secondary_ciphers can only consist of SymmetricEncryption::Ciphers') unless cipher.respond_to?(:encrypt) && cipher.respond_to?(:decrypt) end - @@secondary_ciphers = secondary_ciphers + @secondary_ciphers = secondary_ciphers end # Returns the Primary Symmetric Cipher being used def self.secondary_ciphers - @@secondary_ciphers + @secondary_ciphers end + # Whether to randomize the iv by default. + # true: Generate a new random IV by default. [HIGHLY RECOMMENDED] + # false: Do not generate a new random IV by default. + def self.randomize_iv? + @randomize_iv + end + + def self.randomize_iv=(randomize_iv) + @randomize_iv = randomize_iv + end + # Decrypt supplied string. # # Returns [String] the decrypted string. # Returns [nil] if the supplied value is nil. # Returns [''] if it is a string and it is empty. @@ -131,13 +137,13 @@ else c = if version # Supplied version takes preference cipher(version) - elsif @@select_cipher + elsif @select_cipher # Use cipher_selector if present to decide which cipher to use - @@select_cipher.call(str, decoded) + @select_cipher.call(str, decoded) else # Global cipher cipher end c.binary_decrypt(decoded) @@ -170,14 +176,16 @@ # value [Object] # String to be encrypted. If str is not a string, #to_s will be called on it # to convert it to a string # # random_iv [true|false] - # Whether the encypted value should use a random IV every time the - # field is encrypted. - # It is recommended to set this to true where feasible. If the encrypted - # value could be used as part of a SQL where clause, or as part + # Mandatory unless `SymmetricEncryption.randomize_iv = true` has been called. + # + # Whether the encrypted value should use a random IV every time the field is encrypted. + # It is recommended to set this to true where possible. + # + # If the encrypted value could be used as part of a SQL where clause, or as part # of any lookup, then it must be false. # Setting random_iv to true will result in a different encrypted output for # the same input string. # Note: Only set to true if the field will never be used as part of # the where clause in an SQL query. @@ -201,11 +209,11 @@ # When type is set to :string (the default), uses #to_s to convert # non-string values to string values. # Note: If type is set to something other than :string, it's expected that # the coercible gem is available in the path. # Default: :string - def self.encrypt(str, random_iv: false, compress: false, type: :string, header: cipher.always_add_header) + def self.encrypt(str, random_iv: SymmetricEncryption.randomize_iv?, compress: false, type: :string, header: cipher.always_add_header) return str if str.nil? || (str == '') # Encrypt and then encode the supplied string cipher.encrypt(Coerce.coerce_to_string(str, type), random_iv: random_iv, compress: compress, header: header) end @@ -263,11 +271,11 @@ # # Use cipher version 0 if the encoded string ends with "\n" otherwise # # use the current default cipher # encoded_str.end_with?("\n") ? SymmetricEncryption.cipher(0) : SymmetricEncryption.cipher # end def self.select_cipher(&block) - @@select_cipher = block || nil + @select_cipher = block || nil end # Load the Encryption Configuration from a YAML file # file_name: # Name of file to read. @@ -286,6 +294,12 @@ SecureRandom.urlsafe_base64(size) end BINARY_ENCODING = Encoding.find('binary') UTF8_ENCODING = Encoding.find('UTF-8') + + # Defaults + @cipher = nil + @secondary_ciphers = [] + @select_cipher = nil + @random_iv = false end