lib/symmetric_encryption/symmetric_encryption.rb in symmetric-encryption-1.1.1 vs lib/symmetric_encryption/symmetric_encryption.rb in symmetric-encryption-2.0.0
- old
+ new
@@ -83,15 +83,44 @@
# AES Symmetric Encryption of supplied string
# Returns result as a Base64 encoded string
# Returns nil if the supplied str is nil
# Returns "" if it is a string and it is empty
- def self.encrypt(str)
+ #
+ # Parameters
+ # str [String]
+ # 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
+ # 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.
+ # Note: When random_iv is true it will add a 8 byte header, plus the bytes
+ # to store the random IV in every returned encrypted string, prior to the
+ # encoding if any.
+ # Default: false
+ # Highly Recommended where feasible: true
+ #
+ # compress [true|false]
+ # Whether to compress str before encryption
+ # Should only be used for large strings since compression overhead and
+ # the overhead of adding the 'magic' header may exceed any benefits of
+ # compression
+ # Note: Adds a 6 byte header prior to encoding, only if :random_iv is false
+ # Default: false
+ def self.encrypt(str, random_iv=false, compress=false)
raise "Call SymmetricEncryption.load! or SymmetricEncryption.cipher= prior to encrypting or decrypting data" unless @@cipher
# Encrypt and then encode the supplied string
- @@cipher.encrypt(str)
+ @@cipher.encrypt(str, random_iv, compress)
end
# Invokes decrypt
# Returns decrypted String
# Return nil if it fails to decrypt a String
@@ -157,17 +186,17 @@
def self.generate_symmetric_key_files(filename=nil, environment=nil)
config = read_config(filename, environment)
cipher_cfg = config[:ciphers].first
key_filename = cipher_cfg[:key_filename]
iv_filename = cipher_cfg[:iv_filename]
- cipher = cipher_cfg[:cipher]
+ cipher_name = cipher_cfg[:cipher_name] || cipher_cfg[:cipher]
raise "The configuration file must contain a 'private_rsa_key' parameter to generate symmetric keys" unless config[:private_rsa_key]
rsa_key = OpenSSL::PKey::RSA.new(config[:private_rsa_key])
# Generate a new Symmetric Key pair
- key_pair = SymmetricEncryption::Cipher.random_key_pair(cipher || 'aes-256-cbc', !iv_filename.nil?)
+ key_pair = SymmetricEncryption::Cipher.random_key_pair(cipher_name || 'aes-256-cbc', !iv_filename.nil?)
# Save symmetric key after encrypting it with the private RSA key, backing up existing files if present
File.rename(key_filename, "#{key_filename}.#{Time.now.to_i}") if File.exist?(key_filename)
File.open(key_filename, 'wb') {|file| file.write( rsa_key.public_encrypt(key_pair[:key]) ) }
@@ -205,29 +234,29 @@
# Which environments config to load. Usually: production, development, etc.
def self.read_config(filename=nil, environment=nil)
config = YAML.load_file(filename || File.join(Rails.root, "config", "symmetric-encryption.yml"))[environment || Rails.env]
# Default cipher
- default_cipher = config['cipher'] || 'aes-256-cbc'
+ default_cipher = config['cipher_name'] || config['cipher'] || 'aes-256-cbc'
cfg = {}
# Hard coded symmetric_key? - Dev / Testing use only!
if symmetric_key = (config['key'] || config['symmetric_key'])
raise "SymmetricEncryption Cannot hard code Production encryption keys in #{filename}" if (environment || Rails.env) == 'production'
- cfg[:key] = symmetric_key
- cfg[:iv] = config['iv'] || config['symmetric_iv']
- cfg[:cipher] = default_cipher
+ cfg[:key] = symmetric_key
+ cfg[:iv] = config['iv'] || config['symmetric_iv']
+ cfg[:cipher_name] = default_cipher
elsif ciphers = config['ciphers']
raise "Missing mandatory config parameter 'private_rsa_key'" unless cfg[:private_rsa_key] = config['private_rsa_key']
cfg[:ciphers] = ciphers.collect do |cipher_cfg|
key_filename = cipher_cfg['key_filename'] || cipher_cfg['symmetric_key_filename']
raise "Missing mandatory 'key_filename' for environment:#{environment} in #{filename}" unless key_filename
iv_filename = cipher_cfg['iv_filename'] || cipher_cfg['symmetric_iv_filename']
{
- :cipher => cipher_cfg['cipher'] || default_cipher,
+ :cipher_name => cipher_cfg['cipher_name'] || cipher_cfg['cipher'] || default_cipher,
:key_filename => key_filename,
:iv_filename => iv_filename,
:encoding => cipher_cfg['encoding'],
:version => cipher_cfg['version']
}
@@ -235,11 +264,11 @@
else
# Migrate old format config
raise "Missing mandatory config parameter 'private_rsa_key'" unless cfg[:private_rsa_key] = config['private_rsa_key']
cfg[:ciphers] = [ {
- :cipher => default_cipher,
+ :cipher_name => default_cipher,
:key_filename => config['symmetric_key_filename'],
:iv_filename => config['symmetric_iv_filename'],
} ]
end
@@ -250,20 +279,21 @@
# stored in files
#
# Raises an Exception on failure
#
# Parameters:
- # cipher
- # Encryption cipher for the symmetric encryption key
- # private_key
+ # private_rsa_key
# Key used to unlock file containing the actual symmetric key
- # key_filename
- # Name of file containing symmetric key encrypted using the public
- # key matching the supplied private_key
- # iv_filename
- # Optional. Name of file containing symmetric key initialization vector
- # encrypted using the public key matching the supplied private_key
+ # cipher_conf Hash:
+ # cipher_name
+ # Encryption cipher name for the symmetric encryption key
+ # key_filename
+ # Name of file containing symmetric key encrypted using the public
+ # key matching the supplied private_key
+ # iv_filename
+ # Optional. Name of file containing symmetric key initialization vector
+ # encrypted using the public key matching the supplied private_key
def self.cipher_from_encrypted_files(private_rsa_key, cipher_conf)
# Load Encrypted Symmetric keys
key_filename = cipher_conf[:key_filename]
encrypted_key = begin
File.read(key_filename)
@@ -284,14 +314,14 @@
# Decrypt Symmetric Keys
rsa = OpenSSL::PKey::RSA.new(private_rsa_key)
iv = rsa.private_decrypt(encrypted_iv) if iv_filename
Cipher.new(
- :key => rsa.private_decrypt(encrypted_key),
- :iv => iv,
- :cipher => cipher_conf[:cipher],
- :encoding => cipher_conf[:encoding],
- :version => cipher_conf[:version]
+ :key => rsa.private_decrypt(encrypted_key),
+ :iv => iv,
+ :cipher_name => cipher_conf[:cipher_name],
+ :encoding => cipher_conf[:encoding],
+ :version => cipher_conf[:version]
)
end
# With Ruby 1.9 strings have encodings
if defined?(Encoding)
\ No newline at end of file