inline_encryption 1.0.3 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +2 -1
- data/.pre-commit-config.yaml +21 -0
- data/.rubocop.yml +12 -0
- data/.rubocop_todo.yml +20 -0
- data/.tool-versions +2 -0
- data/.travis.yml +5 -3
- data/CHANGELOG.md +32 -0
- data/Gemfile +13 -5
- data/Guardfile +6 -11
- data/README.md +25 -0
- data/Rakefile +5 -3
- data/bin/inline_encryption +2 -0
- data/config/locales.yml +2 -0
- data/inline_encryption.gemspec +14 -15
- data/lib/inline_encryption/base.rb +19 -23
- data/lib/inline_encryption/cli.rb +6 -11
- data/lib/inline_encryption/config.rb +23 -15
- data/lib/inline_encryption/errors.rb +4 -3
- data/lib/inline_encryption/version.rb +3 -1
- data/lib/inline_encryption.rb +3 -2
- data/spec/inline_encryption/base_spec.rb +35 -36
- data/spec/inline_encryption/cli_spec.rb +7 -12
- data/spec/inline_encryption/config_spec.rb +18 -21
- data/spec/inline_encryption_spec.rb +4 -4
- data/spec/spec_helper.rb +8 -15
- metadata +37 -79
- data/test_app/.gitignore +0 -16
- data/test_app/Gemfile +0 -6
- data/test_app/README.rdoc +0 -28
- data/test_app/Rakefile +0 -6
- data/test_app/app/assets/images/.keep +0 -0
- data/test_app/app/assets/javascripts/application.js +0 -16
- data/test_app/app/assets/stylesheets/application.css +0 -13
- data/test_app/app/controllers/application_controller.rb +0 -5
- data/test_app/app/controllers/concerns/.keep +0 -0
- data/test_app/app/helpers/application_helper.rb +0 -2
- data/test_app/app/mailers/.keep +0 -0
- data/test_app/app/models/.keep +0 -0
- data/test_app/app/models/concerns/.keep +0 -0
- data/test_app/app/views/layouts/application.html.erb +0 -14
- data/test_app/bin/bundle +0 -3
- data/test_app/bin/rails +0 -4
- data/test_app/bin/rake +0 -4
- data/test_app/config/application.rb +0 -23
- data/test_app/config/boot.rb +0 -4
- data/test_app/config/database.yml +0 -25
- data/test_app/config/environment.rb +0 -5
- data/test_app/config/environments/development.rb +0 -29
- data/test_app/config/environments/production.rb +0 -80
- data/test_app/config/environments/test.rb +0 -36
- data/test_app/config/initializers/backtrace_silencers.rb +0 -7
- data/test_app/config/initializers/filter_parameter_logging.rb +0 -4
- data/test_app/config/initializers/inflections.rb +0 -16
- data/test_app/config/initializers/mime_types.rb +0 -5
- data/test_app/config/initializers/secret_token.rb +0 -12
- data/test_app/config/initializers/session_store.rb +0 -3
- data/test_app/config/initializers/wrap_parameters.rb +0 -14
- data/test_app/config/locales/en.yml +0 -23
- data/test_app/config/routes.rb +0 -56
- data/test_app/config.ru +0 -4
- data/test_app/db/seeds.rb +0 -7
- data/test_app/lib/assets/.keep +0 -0
- data/test_app/lib/tasks/.keep +0 -0
- data/test_app/log/.keep +0 -0
- data/test_app/public/404.html +0 -58
- data/test_app/public/422.html +0 -58
- data/test_app/public/500.html +0 -57
- data/test_app/public/favicon.ico +0 -0
- data/test_app/public/robots.txt +0 -5
- data/test_app/test/controllers/.keep +0 -0
- data/test_app/test/fixtures/.keep +0 -0
- data/test_app/test/helpers/.keep +0 -0
- data/test_app/test/integration/.keep +0 -0
- data/test_app/test/mailers/.keep +0 -0
- data/test_app/test/models/.keep +0 -0
- data/test_app/test/test_helper.rb +0 -15
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 8579ebc960ba6c9f084553a3f948c18aa15013c5ceda7d4ff9d84191b386defa
|
|
4
|
+
data.tar.gz: cbb00c55dadcfba3f757e90222aa04e5779037afd9fee2b0fddaf35937c06983
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 9a4d667b844ce6bdd816022d4abd763a6488d89cec23e9e32680748e6f2a9eb6e5d489ae419c6a9eb5f1382ba7579e7997334aa8581fd144312293a23aea0f5f
|
|
7
|
+
data.tar.gz: 1adff188699044cf0e9facff5393e96a47f20393335b7ee45e5de761fa438ced3d8b3b5865d9b87755c8b5137f380b9771d08732d6ad28cac9201e54dcae6c95
|
data/.gitignore
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- hooks:
|
|
3
|
+
- id: check-added-large-files
|
|
4
|
+
- id: check-merge-conflict
|
|
5
|
+
- id: check-yaml
|
|
6
|
+
- id: detect-aws-credentials
|
|
7
|
+
- id: detect-private-key
|
|
8
|
+
- id: end-of-file-fixer
|
|
9
|
+
- id: trailing-whitespace
|
|
10
|
+
repo: https://github.com/pre-commit/pre-commit-hooks
|
|
11
|
+
rev: v4.1.0
|
|
12
|
+
- hooks:
|
|
13
|
+
- id: commitizen
|
|
14
|
+
stages:
|
|
15
|
+
- commit-msg
|
|
16
|
+
repo: https://github.com/commitizen-tools/commitizen
|
|
17
|
+
rev: v2.20.3
|
|
18
|
+
- hooks:
|
|
19
|
+
- id: rubocop
|
|
20
|
+
repo: https://github.com/jumanjihouse/pre-commit-hooks
|
|
21
|
+
rev: 2.1.5
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
|
2
|
+
|
|
3
|
+
# The behavior of RuboCop can be controlled via the .rubocop.yml
|
|
4
|
+
# configuration file. It makes it possible to enable/disable
|
|
5
|
+
# certain cops (checks) and to alter their behavior if they accept
|
|
6
|
+
# any parameters. The file can be placed either in your home
|
|
7
|
+
# directory or in some project directory.
|
|
8
|
+
#
|
|
9
|
+
# RuboCop will start looking for the configuration file in the directory
|
|
10
|
+
# where the inspected file is and continue its way up to the root directory.
|
|
11
|
+
#
|
|
12
|
+
# See https://docs.rubocop.org/rubocop/configuration
|
data/.rubocop_todo.yml
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# This configuration was generated by
|
|
2
|
+
# `rubocop --auto-gen-config`
|
|
3
|
+
# on 2022-01-11 17:25:54 UTC using RuboCop version 1.24.1.
|
|
4
|
+
# The point is for the user to remove these configuration records
|
|
5
|
+
# one by one as the offenses are removed from the code base.
|
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
|
8
|
+
|
|
9
|
+
# Offense count: 1
|
|
10
|
+
# Configuration parameters: Include.
|
|
11
|
+
# Include: **/*.gemspec
|
|
12
|
+
Gemspec/RequiredRubyVersion:
|
|
13
|
+
Exclude:
|
|
14
|
+
- 'inline_encryption.gemspec'
|
|
15
|
+
|
|
16
|
+
# Offense count: 4
|
|
17
|
+
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
|
|
18
|
+
# IgnoredMethods: refine
|
|
19
|
+
Metrics/BlockLength:
|
|
20
|
+
Max: 63
|
data/.tool-versions
ADDED
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# 2.0.1
|
|
2
|
+
- update test app to latest Rails 4 to satisfy automated security scan; future versions
|
|
3
|
+
will probably drop the included test app
|
|
4
|
+
- updated travis to drop ruby 2.1, update 2.2 and 2.3 to latest; add ruby 2.4 and 2.5
|
|
5
|
+
|
|
6
|
+
# 2.0.0
|
|
7
|
+
- Major backwards compatible change. A common if perhaps upspoken thought
|
|
8
|
+
of many good developers I have known is "I hate what I wrote yesterday"
|
|
9
|
+
Well, for whatever reason (that I cannot recall or even fathom) this gem was
|
|
10
|
+
originally written using a private key for encrypting a value, and a public
|
|
11
|
+
key to decrypt. While that is not itself insecure, it's a terrible
|
|
12
|
+
practice and makes it easy for humans to make errors.
|
|
13
|
+
So starting in version 2.0.0 encrpyt methods will use public key and
|
|
14
|
+
decrypt will use private key, as is conventional
|
|
15
|
+
- raise on trying to decrypt with a public key
|
|
16
|
+
- code cleanup (style, remove spork remnant)
|
|
17
|
+
- bump travis ruby versions to secure versions
|
|
18
|
+
|
|
19
|
+
# 1.0.5
|
|
20
|
+
- updated gem groups, updated travis to run without debugger and development groups
|
|
21
|
+
# 1.0.4
|
|
22
|
+
- update version of Bundler to floor 1.7
|
|
23
|
+
- swapped byebug for debugger
|
|
24
|
+
- fixed a few style violations (single/double quotes)
|
|
25
|
+
- added Thor to runtime dependencies
|
|
26
|
+
- added explicit require for hashie/dash and hashie/extensions/dash/indifferent_access in config.rb
|
|
27
|
+
I think this is probably unnecessary but was getting unresolved name errors in some rubies
|
|
28
|
+
- added explicit require for base64 in base.rb ([Issue #2](https://github.com/rubyisbeautiful/inline_encryption/issues/2))
|
|
29
|
+
- drop 1.9.x and 2.0.x in travis testing
|
|
30
|
+
- updated to rspec 3 syntax
|
|
31
|
+
|
|
32
|
+
# 1.0.3
|
data/Gemfile
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
source 'https://rubygems.org'
|
|
2
4
|
|
|
3
5
|
gemspec
|
|
4
6
|
|
|
5
|
-
gem 'bundler', '
|
|
7
|
+
gem 'bundler', '>= 2.2.33'
|
|
6
8
|
gem 'hashie'
|
|
7
9
|
gem 'i18n'
|
|
8
10
|
gem 'thor'
|
|
9
11
|
|
|
10
|
-
group :
|
|
11
|
-
gem '
|
|
12
|
+
group :debugger do
|
|
13
|
+
gem 'byebug', '~> 11'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
group :development do
|
|
12
17
|
gem 'guard'
|
|
13
18
|
gem 'guard-rspec'
|
|
14
|
-
gem '
|
|
19
|
+
gem 'rubocop'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
group :development, :test do
|
|
15
23
|
gem 'rake'
|
|
16
24
|
gem 'redcarpet'
|
|
17
25
|
gem 'rspec'
|
|
18
26
|
gem 'simplecov', require: false
|
|
19
27
|
gem 'yard'
|
|
20
|
-
end
|
|
28
|
+
end
|
data/Guardfile
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# A sample Guardfile
|
|
2
4
|
# More info at https://github.com/guard/guard#readme
|
|
3
5
|
|
|
4
|
-
guard 'rspec', all_after_pass: true, failed_mode: :focus, all_on_start: true, cmd: 'rspec
|
|
6
|
+
guard 'rspec', all_after_pass: true, failed_mode: :focus, all_on_start: true, cmd: 'rspec' do
|
|
5
7
|
watch(%r{^spec/.+_spec\.rb$})
|
|
6
|
-
watch(%r{^lib/(.+)\.rb$}){ |m| "spec/lib/#{m[1]}_spec.rb" }
|
|
7
|
-
watch('spec/spec_helper.rb'){
|
|
8
|
-
watch(%r{^spec/support/(.+)\.rb$})
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
guard 'spork', :test_unit => false do
|
|
12
|
-
watch('Gemfile')
|
|
13
|
-
watch('Gemfile.lock')
|
|
14
|
-
watch('spec/spec_helper.rb') { :rspec }
|
|
8
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
|
9
|
+
watch('spec/spec_helper.rb') { 'spec' }
|
|
10
|
+
watch(%r{^spec/support/(.+)\.rb$}) { 'spec' }
|
|
15
11
|
end
|
|
16
|
-
|
data/README.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Simple encryption relying on convention and designed to be used inline as string replacements.
|
|
4
4
|
|
|
5
|
+
PLEASE upgrade to version 2.0 - previous versions lend themselves to making
|
|
6
|
+
human errors which could lead to exploitation.
|
|
7
|
+
|
|
8
|
+
## Upgrading from 1.0 to 2.0
|
|
9
|
+
|
|
10
|
+
1. Recommended, but optional - generate a new RSA key pair
|
|
11
|
+
2. For a properly configured production environment, simply configure with a private key
|
|
12
|
+
3. Pass along the public key to any developers on the team that will need to encrypt new values
|
|
13
|
+
|
|
5
14
|
## Usage
|
|
6
15
|
|
|
7
16
|
Imagine you have a file named `database.yml` that contains passwords.
|
|
@@ -17,3 +26,19 @@ After:
|
|
|
17
26
|
```ruby
|
|
18
27
|
password: <%= InlineEncryption.decrypt(encrypted stuff goes here) %>
|
|
19
28
|
```
|
|
29
|
+
|
|
30
|
+
To set up:
|
|
31
|
+
|
|
32
|
+
```ruby
|
|
33
|
+
InlineEncryption.config[:key] = '/some/rsa_key'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
An example of different keys per environment:
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
InlineEncryption.config[:key] = ENV['INLINE_ENCRYPTION_KEY']
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
If you've configured with a private key, you can both encrypt and decrypt. If you've
|
|
44
|
+
configured with a public key, you can only encrypt.
|
data/Rakefile
CHANGED
data/bin/inline_encryption
CHANGED
data/config/locales.yml
CHANGED
|
@@ -3,8 +3,10 @@ en:
|
|
|
3
3
|
encrypted: 'Encrypted: %{data}'
|
|
4
4
|
error:
|
|
5
5
|
missing_key: "missing variable: 'key'"
|
|
6
|
+
pub_key_decrypt: "Tried to decrypt with a public key. If you really need this ability, please use version ~> 1.0"
|
|
6
7
|
es:
|
|
7
8
|
target: 'Destino: %{data}'
|
|
8
9
|
encrypted: 'Encriptado: %{data}'
|
|
9
10
|
error:
|
|
10
11
|
missing_key: "variable que falta: 'key'"
|
|
12
|
+
pub_key_decrypt: "Intentado decriptar con llave publica. Si de veras necesitas esta capabilidad, favor de user version ~> 1.0"
|
data/inline_encryption.gemspec
CHANGED
|
@@ -1,29 +1,28 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'English'
|
|
4
|
+
lib = File.expand_path('lib', __dir__)
|
|
4
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
6
|
require 'inline_encryption/version'
|
|
6
7
|
|
|
7
8
|
Gem::Specification.new do |spec|
|
|
8
|
-
spec.name =
|
|
9
|
+
spec.name = 'inline_encryption'
|
|
9
10
|
spec.version = InlineEncryption::VERSION
|
|
10
11
|
spec.authors = ['rubyisbeautiful']
|
|
11
|
-
spec.email =
|
|
12
|
-
spec.description =
|
|
13
|
-
spec.summary =
|
|
14
|
-
spec.homepage = '
|
|
12
|
+
spec.email = 'bcptaylor+github@gmail.com'
|
|
13
|
+
spec.description = ' A simple encryption tool based on common convention '
|
|
14
|
+
spec.summary = ' A drop-in simple encryption tool for stringish things '
|
|
15
|
+
spec.homepage = 'https://github.com/rubyisbeautiful/inline_encryption'
|
|
15
16
|
spec.license = 'MIT'
|
|
16
17
|
|
|
17
|
-
spec.files = `git ls-files`.split(
|
|
18
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
|
19
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
20
|
-
spec.require_paths = [
|
|
21
|
-
spec.required_ruby_version = '>= 1.
|
|
20
|
+
spec.require_paths = ['lib']
|
|
21
|
+
spec.required_ruby_version = '>= 2.1.5'
|
|
22
22
|
|
|
23
|
-
spec.executables
|
|
23
|
+
spec.executables = ['inline_encryption']
|
|
24
24
|
|
|
25
25
|
spec.add_runtime_dependency 'hashie'
|
|
26
26
|
spec.add_runtime_dependency 'i18n'
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
spec.add_runtime_dependency 'thor'
|
|
29
28
|
end
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
module Base
|
|
1
|
+
# frozen_string_literal: true
|
|
4
2
|
|
|
3
|
+
require 'base64'
|
|
5
4
|
|
|
5
|
+
module InlineEncryption
|
|
6
|
+
# Base module including core functionality
|
|
7
|
+
module Base
|
|
6
8
|
# @param [String] data encryption target
|
|
7
9
|
# @return [String] encrypted target
|
|
8
10
|
# @raise [EncryptionFailureError] couldn't encrypt the target
|
|
@@ -10,64 +12,58 @@ module InlineEncryption
|
|
|
10
12
|
config.check_required_variables
|
|
11
13
|
|
|
12
14
|
begin
|
|
13
|
-
encrypted = config.real_key.
|
|
14
|
-
|
|
15
|
-
rescue
|
|
15
|
+
encrypted = config.real_key.public_encrypt(data)
|
|
16
|
+
Base64.encode64(encrypted)
|
|
17
|
+
rescue StandardError
|
|
16
18
|
err = EncryptionFailureError.exception I18n.t('target', data: data)
|
|
17
19
|
raise err
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
|
|
22
23
|
# @param [String] data encryption target
|
|
23
24
|
# @return [String] encrypted target, or fail_text on error (default data)
|
|
24
|
-
def encrypt(data, fail_text=nil)
|
|
25
|
+
def encrypt(data, fail_text = nil)
|
|
25
26
|
config.check_required_variables
|
|
26
27
|
|
|
27
28
|
begin
|
|
28
29
|
encrypt!(data)
|
|
29
|
-
rescue EncryptionFailureError
|
|
30
|
-
|
|
30
|
+
rescue EncryptionFailureError
|
|
31
|
+
fail_text.nil? ? data : fail_text.to_s
|
|
31
32
|
end
|
|
32
33
|
end
|
|
33
34
|
|
|
34
|
-
|
|
35
35
|
# @param [String] data decryption target
|
|
36
36
|
# @return [String] decrypted target
|
|
37
37
|
# @raise [DecryptionFailureError] couldn't decrypt the target
|
|
38
38
|
def decrypt!(data)
|
|
39
39
|
config.check_required_variables
|
|
40
|
+
raise MisconfigurationError, I18n.t('error.pub_key_decrypt') unless config.real_key.private?
|
|
40
41
|
|
|
41
42
|
begin
|
|
42
43
|
converted = Base64.decode64(data)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
err = DecryptionFailureError.exception I18n.t('encrypted', data)
|
|
44
|
+
config.real_key.private_decrypt(converted)
|
|
45
|
+
rescue StandardError
|
|
46
|
+
err = DecryptionFailureError.exception I18n.t('encrypted', data: data)
|
|
47
47
|
raise err
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
|
|
52
51
|
# @param [String] data decryption target
|
|
53
52
|
# @param [String] fail_text text to be returned in the case of a decryption failure
|
|
54
53
|
# @return [String] decrypted target
|
|
55
|
-
def decrypt(data, fail_text=nil)
|
|
54
|
+
def decrypt(data, fail_text = nil)
|
|
56
55
|
config.check_required_variables
|
|
57
56
|
|
|
58
57
|
begin
|
|
59
58
|
decrypt!(data)
|
|
60
|
-
rescue DecryptionFailureError
|
|
61
|
-
|
|
59
|
+
rescue DecryptionFailureError
|
|
60
|
+
fail_text.nil? ? data : fail_text.to_s
|
|
62
61
|
end
|
|
63
62
|
end
|
|
64
63
|
|
|
65
|
-
|
|
66
64
|
# @return [InlineEncryption::Config] the configuration instance
|
|
67
65
|
def config
|
|
68
66
|
@config ||= Config.new
|
|
69
67
|
end
|
|
70
|
-
|
|
71
68
|
end
|
|
72
|
-
|
|
73
|
-
end
|
|
69
|
+
end
|
|
@@ -1,31 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'thor'
|
|
2
4
|
|
|
3
5
|
module InlineEncryption
|
|
4
|
-
|
|
6
|
+
# CLI class for using on commandline
|
|
5
7
|
class CLI < Thor
|
|
6
|
-
|
|
7
|
-
def initialize(args=[], opts=[], config={})
|
|
8
|
+
def initialize(args = [], opts = [], config = {})
|
|
8
9
|
super(args, opts, config)
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
|
|
12
12
|
desc 'encrypt [DATA]', 'encrypt stuff'
|
|
13
|
-
class_option :require, :
|
|
13
|
+
class_option :require, aliases: ['-r'], type: :string
|
|
14
14
|
def encrypt(data)
|
|
15
15
|
load_environment(options[:require]) if options[:require]
|
|
16
16
|
|
|
17
17
|
puts InlineEncryption.encrypt(data)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
20
|
protected
|
|
23
21
|
|
|
24
|
-
|
|
25
22
|
def load_environment(file)
|
|
26
23
|
require File.expand_path(file)
|
|
27
24
|
end
|
|
28
|
-
|
|
29
25
|
end
|
|
30
|
-
|
|
31
|
-
end
|
|
26
|
+
end
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'hashie/extensions/ruby_version_check'
|
|
1
4
|
require 'hashie/extensions/indifferent_access'
|
|
2
5
|
require 'hashie/extensions/method_access'
|
|
6
|
+
require 'hashie/extensions/dash/indifferent_access'
|
|
7
|
+
require 'hashie/dash'
|
|
3
8
|
require 'openssl'
|
|
4
9
|
|
|
5
10
|
module InlineEncryption
|
|
6
|
-
|
|
7
11
|
# known configuration variables
|
|
8
12
|
# key - a String containing the private key, a filename pointing to the private key, or an OpenSSL::PKey::RSA
|
|
9
13
|
class Config < Hash
|
|
@@ -13,26 +17,30 @@ module InlineEncryption
|
|
|
13
17
|
# checks required, currently only the 'key'
|
|
14
18
|
# @raises [InlineEncryption::MissingRequiredVariableError] raise on a missing variable
|
|
15
19
|
def check_required_variables
|
|
16
|
-
raise MissingRequiredVariableError
|
|
20
|
+
raise MissingRequiredVariableError, I18n.t('error.missing_key') unless key?(:key)
|
|
17
21
|
end
|
|
18
22
|
|
|
19
|
-
|
|
20
23
|
# @return [OpenSSL::PKey::RSA] the OpenSSL key instance
|
|
21
24
|
def real_key
|
|
22
25
|
case self[:key]
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
OpenSSL::PKey::RSA.new(self[:key])
|
|
30
|
-
end
|
|
31
|
-
when OpenSSL::PKey::RSA
|
|
32
|
-
self[:key]
|
|
26
|
+
when NilClass
|
|
27
|
+
nil
|
|
28
|
+
when String
|
|
29
|
+
load_or_use_key(self[:key])
|
|
30
|
+
when OpenSSL::PKey::RSA
|
|
31
|
+
self[:key]
|
|
33
32
|
end
|
|
34
33
|
end
|
|
35
|
-
end
|
|
36
34
|
|
|
35
|
+
private
|
|
37
36
|
|
|
38
|
-
|
|
37
|
+
# @return OpenSSL::PKey::RSA
|
|
38
|
+
def load_or_use_key(str)
|
|
39
|
+
if File.exist?(str)
|
|
40
|
+
OpenSSL::PKey::RSA.new(File.read(str))
|
|
41
|
+
else
|
|
42
|
+
OpenSSL::PKey::RSA.new(str)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
module InlineEncryption
|
|
3
4
|
class MissingRequiredVariableError < StandardError; end
|
|
4
5
|
class DecryptionFailureError < StandardError; end
|
|
5
6
|
class EncryptionFailureError < StandardError; end
|
|
6
|
-
|
|
7
|
-
end
|
|
7
|
+
class MisconfigurationError < StandardError; end
|
|
8
|
+
end
|
data/lib/inline_encryption.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'i18n'
|
|
2
4
|
require 'base64'
|
|
3
5
|
require 'inline_encryption/version'
|
|
@@ -5,6 +7,7 @@ require 'inline_encryption/config'
|
|
|
5
7
|
require 'inline_encryption/base'
|
|
6
8
|
require 'inline_encryption/errors'
|
|
7
9
|
|
|
10
|
+
# top level module InlineEncryption
|
|
8
11
|
module InlineEncryption
|
|
9
12
|
extend InlineEncryption::Base
|
|
10
13
|
|
|
@@ -14,6 +17,4 @@ module InlineEncryption
|
|
|
14
17
|
I18n.enforce_available_locales = false
|
|
15
18
|
@_i18n_initialized_for_ie = true
|
|
16
19
|
end
|
|
17
|
-
|
|
18
|
-
|
|
19
20
|
end
|
|
@@ -1,88 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
require 'base64'
|
|
3
5
|
|
|
4
6
|
describe InlineEncryption::Base do
|
|
5
|
-
|
|
6
7
|
before :all do
|
|
7
8
|
@default_key = OpenSSL::PKey::RSA.generate(2048)
|
|
8
9
|
end
|
|
9
10
|
|
|
10
|
-
before :each do
|
|
11
|
-
InlineEncryption.config[:key] = @default_key
|
|
12
|
-
end
|
|
13
|
-
|
|
14
11
|
describe 'encrypt' do
|
|
12
|
+
let(:str) { 'foo' }
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
before :each do
|
|
15
|
+
InlineEncryption.config[:key] = @default_key
|
|
16
|
+
end
|
|
17
17
|
|
|
18
18
|
it 'should encrypt' do
|
|
19
|
-
InlineEncryption.encrypt(str).
|
|
19
|
+
expect(InlineEncryption.encrypt(str)).not_to eq(str)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
it 'should fail to encrpyt and return the target' do
|
|
23
|
-
InlineEncryption.config[:key] = OpenSSL::PKey::RSA.generate(
|
|
24
|
-
InlineEncryption.encrypt(
|
|
23
|
+
InlineEncryption.config[:key] = OpenSSL::PKey::RSA.generate(2048)
|
|
24
|
+
expect(InlineEncryption.encrypt(nil)).to eq(nil)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it 'should fail to encrypt and return the fail_text' do
|
|
28
|
-
InlineEncryption.config[:key] = OpenSSL::PKey::RSA.generate(
|
|
29
|
-
InlineEncryption.encrypt(
|
|
28
|
+
InlineEncryption.config[:key] = OpenSSL::PKey::RSA.generate(2048)
|
|
29
|
+
expect(InlineEncryption.encrypt(nil, 'chunky')).to eq('chunky')
|
|
30
30
|
end
|
|
31
|
-
|
|
32
31
|
end
|
|
33
32
|
|
|
34
33
|
describe 'encrypt!' do
|
|
35
|
-
let(:str){ 'foo' }
|
|
34
|
+
let(:str) { 'foo' }
|
|
35
|
+
|
|
36
|
+
before :each do
|
|
37
|
+
InlineEncryption.config[:key] = @default_key
|
|
38
|
+
end
|
|
36
39
|
|
|
37
40
|
it 'should encrypt' do
|
|
38
|
-
InlineEncryption.encrypt!(str).
|
|
41
|
+
expect(InlineEncryption.encrypt!(str)).not_to eq(str)
|
|
39
42
|
end
|
|
40
43
|
|
|
41
44
|
it 'should fail to encrpyt and raise' do
|
|
42
|
-
InlineEncryption.config[:key] = OpenSSL::PKey::RSA.generate(
|
|
43
|
-
expect{ InlineEncryption.encrypt!(
|
|
45
|
+
InlineEncryption.config[:key] = OpenSSL::PKey::RSA.generate(2048)
|
|
46
|
+
expect { InlineEncryption.encrypt!(nil) }.to raise_error(InlineEncryption::EncryptionFailureError)
|
|
44
47
|
end
|
|
45
|
-
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
describe 'decrypt' do
|
|
49
|
-
|
|
50
|
-
before :all do
|
|
51
|
-
@str = Base64.encode64(@default_key.private_encrypt('chunky'))
|
|
52
|
-
end
|
|
51
|
+
let(:str) { Base64.encode64(@default_key.public_encrypt('chunky')) }
|
|
53
52
|
|
|
54
53
|
it 'should decrypt' do
|
|
55
|
-
InlineEncryption.
|
|
54
|
+
InlineEncryption.config[:key] = @default_key
|
|
55
|
+
expect(InlineEncryption.decrypt(str)).to eq('chunky')
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
it 'should fail to decrypt and return the target' do
|
|
59
|
-
InlineEncryption.config[:key] = OpenSSL::PKey::RSA.generate(
|
|
60
|
-
InlineEncryption.decrypt(
|
|
59
|
+
InlineEncryption.config[:key] = OpenSSL::PKey::RSA.generate(2048)
|
|
60
|
+
expect(InlineEncryption.decrypt(str)).to eq(str)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
it 'should fail to decrypt and return the fail_text' do
|
|
64
|
-
InlineEncryption.config[:key] = OpenSSL::PKey::RSA.generate(
|
|
65
|
-
InlineEncryption.decrypt(
|
|
64
|
+
InlineEncryption.config[:key] = OpenSSL::PKey::RSA.generate(2048)
|
|
65
|
+
expect(InlineEncryption.decrypt(str, 'chunky')).to eq('chunky')
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
+
it 'should fail to decrpyt and raise if using a public key to decrypt' do
|
|
69
|
+
InlineEncryption.config[:key] = @default_key.public_key
|
|
70
|
+
expect { InlineEncryption.decrypt('whatevs') }.to raise_error(InlineEncryption::MisconfigurationError)
|
|
71
|
+
end
|
|
68
72
|
end
|
|
69
73
|
|
|
70
74
|
describe 'decrypt!' do
|
|
71
|
-
|
|
72
|
-
before :all do
|
|
73
|
-
@str = Base64.encode64(@default_key.private_encrypt('chunky'))
|
|
74
|
-
end
|
|
75
|
+
let(:str) { Base64.encode64(@default_key.public_encrypt('chunky')) }
|
|
75
76
|
|
|
76
77
|
it 'should decrypt' do
|
|
77
|
-
InlineEncryption.
|
|
78
|
+
InlineEncryption.config[:key] = @default_key
|
|
79
|
+
expect(InlineEncryption.decrypt!(str)).to eq('chunky')
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
it 'should fail to decrpyt and raise' do
|
|
81
|
-
InlineEncryption.config[:key] = OpenSSL::PKey::RSA.generate(
|
|
82
|
-
expect{ InlineEncryption.decrypt!(
|
|
83
|
+
InlineEncryption.config[:key] = OpenSSL::PKey::RSA.generate(2048)
|
|
84
|
+
expect { InlineEncryption.decrypt!(str) }.to raise_error(InlineEncryption::DecryptionFailureError)
|
|
83
85
|
end
|
|
84
|
-
|
|
85
86
|
end
|
|
86
|
-
|
|
87
87
|
end
|
|
88
|
-
|