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