Module: EasyCrypt

Defined in:
lib/easy_crypt.rb,
lib/easy_crypt/version.rb,
lib/easy_crypt/exception.rb,
lib/easy_crypt/secrets_provider.rb,
lib/easy_crypt/secrets_provider/base.rb,
lib/easy_crypt/secrets_provider/env_provider.rb,
lib/easy_crypt/secrets_provider/rails_credentials_provider.rb

Overview

EasyCrypt

EasyCrypt is a Ruby utility that provides secure and flexible encryption/decryption capabilities for Ruby on Rails applications.

Features


  • Multiple secrets providers support (environment variables and Rails credentials)

  • Configurable encryption cipher

  • Purpose-based encryption/decryption

  • Built on top of Rails’ ActiveSupport::MessageEncryptor

  • Simple and intuitive API

Installation


Add this line to your application’s Gemfile:

gem 'easy_crypt'

Then execute:

$ bundle install

Or install it yourself as:

$ gem install easy_crypt

Configuration


Create an initializer at config/initializers/easy_crypt.rb:

“‘ruby EasyCrypt.configure do |config|

# Choose your secrets provider. Currently supports :rails_credentials or :env_vars.
# Default to :rails_credentials
config.secrets_provider = :rails_credentials

# Set your default cipher (optional)
# Default to `ActiveSupport::MessageEncryptor.default_cipher` which is set to
# 'aes-256-gcm' or 'aes-256-cbc' as of now, depending on your application configuration.
# See `use_authenticated_message_encryption` configuration option for more information.
# See `OpenSSL::Cipher.ciphers` for a list of accepted values.
config.default_cipher = 'aes-256-gcm'

end

Usage


First, you need to configure a secret and a salt for a specific purpose. To do so, you’ll need to use one of the supported secrets providers (currently Rails credentials and env vars) and define a purpose and its credentials.

See ‘EasyCrypt::SecretsProvider` subclasses for more information on how to configure the secrets provider of your choice.

Given that you provided a secret and a salt for the “user_data” purpose, you are able to call the ‘encrypt_user_data` and `decrypt_user_data` methods to directly use the credentials of the “user_data” purpose.

“‘ruby # Encrypt a value encrypted = EasyCrypt.encrypt_user_data(“sensitive information”)

# Decrypt a value decrypted = EasyCrypt.decrypt_user_data(encrypted) “‘

Defined Under Namespace

Classes: InvalidSecretsProvider, MissingSecretsConfigurationError, SecretsProvider

Constant Summary collapse

VERSION =
'1.0.0'

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.default_cipherObject

Returns the value of attribute default_cipher.



84
85
86
# File 'lib/easy_crypt.rb', line 84

def default_cipher
  @default_cipher
end

.secrets_providerObject

Returns the value of attribute secrets_provider.



84
85
86
# File 'lib/easy_crypt.rb', line 84

def secrets_provider
  @secrets_provider
end

Class Method Details

.configure {|config| ... } ⇒ void

This method returns an undefined value.

Configures the EasyCrypt module with custom settings

Examples:

EasyCrypt.configure do |config|
  config.secrets_provider = :env_vars
  config.default_cipher = 'aes-128-gcm'
end

Yield Parameters:

  • config (EasyCrypt)

    The configuration object



96
97
98
# File 'lib/easy_crypt.rb', line 96

def configure
  yield self
end

.method_missing(method_name, *args) ⇒ Object, ...

Note:

If the method name does not match the expected pattern, ‘method_missing` will defer to the superclass implementation, raising a `NoMethodError` if the method is undefined.

Handles dynamic encryption/decryption method calls

This method allows dynamically calling encryption or decryption methods for specific purposes by embedding the purpose directly in the method name. The pattern for such method names is: ‘encrypt_<purpose>` for encryption and `decrypt_<purpose>` for decryption.

For instance:

  • Calling ‘EasyCrypt.encrypt_authentication(value)` will encrypt the provided value using the credentials configured for the `authentication` purpose.

  • Calling ‘EasyCrypt.decrypt_user_data(encrypted_value)` will decrypt the given value using the credentials for the `user_data` purpose.

This dynamic approach enables simple and intuitive APIs without requiring explicit method definitions for each purpose.

Examples:

Encrypting a value for the “authentication” purpose

encrypted = EasyCrypt.encrypt_authentication("my_secret_data")

Decrypting a value for the “user_data” purpose

decrypted = EasyCrypt.decrypt_user_data(encrypted_data)

Returns:

  • (Object, String, nil)

    The encrypted or decrypted value, or nil if decryption fails



125
126
127
128
129
130
131
# File 'lib/easy_crypt.rb', line 125

def method_missing(method_name, *args)
  if /^(?<action>encrypt|decrypt)_(?<purpose>[a-z_]+)$/ =~ method_name
    send(action, *args.unshift(purpose.to_sym))
  else
    super
  end
end

.respond_to_missing?(method_name, include_private) ⇒ Boolean

Checks if a method is supported by the module

Returns:

  • (Boolean)


134
135
136
# File 'lib/easy_crypt.rb', line 134

def respond_to_missing?(method_name, include_private)
  /^(encrypt|decrypt)_[a-z_]+$/ =~ method_name || super
end