symmetric-encryption 4.2.1 → 4.4.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -7
  3. data/Rakefile +9 -9
  4. data/bin/symmetric-encryption +1 -1
  5. data/lib/symmetric-encryption.rb +1 -1
  6. data/lib/symmetric_encryption/{railties → active_record}/attr_encrypted.rb +16 -5
  7. data/lib/symmetric_encryption/active_record/encrypted_attribute.rb +37 -0
  8. data/lib/symmetric_encryption/cipher.rb +20 -14
  9. data/lib/symmetric_encryption/cli.rb +72 -54
  10. data/lib/symmetric_encryption/coerce.rb +3 -3
  11. data/lib/symmetric_encryption/config.rb +28 -27
  12. data/lib/symmetric_encryption/core.rb +25 -20
  13. data/lib/symmetric_encryption/encoder.rb +26 -8
  14. data/lib/symmetric_encryption/generator.rb +7 -3
  15. data/lib/symmetric_encryption/header.rb +24 -24
  16. data/lib/symmetric_encryption/key.rb +1 -1
  17. data/lib/symmetric_encryption/keystore/aws.rb +10 -13
  18. data/lib/symmetric_encryption/keystore/environment.rb +5 -5
  19. data/lib/symmetric_encryption/keystore/file.rb +27 -9
  20. data/lib/symmetric_encryption/keystore/gcp.rb +21 -18
  21. data/lib/symmetric_encryption/keystore/heroku.rb +1 -1
  22. data/lib/symmetric_encryption/keystore/memory.rb +3 -3
  23. data/lib/symmetric_encryption/keystore.rb +23 -23
  24. data/lib/symmetric_encryption/railtie.rb +12 -11
  25. data/lib/symmetric_encryption/railties/mongoid_encrypted.rb +5 -4
  26. data/lib/symmetric_encryption/railties/symmetric_encryption_validator.rb +1 -1
  27. data/lib/symmetric_encryption/reader.rb +13 -13
  28. data/lib/symmetric_encryption/rsa_key.rb +1 -1
  29. data/lib/symmetric_encryption/symmetric_encryption.rb +56 -36
  30. data/lib/symmetric_encryption/utils/aws.rb +8 -10
  31. data/lib/symmetric_encryption/utils/files.rb +3 -3
  32. data/lib/symmetric_encryption/utils/re_encrypt_files.rb +11 -11
  33. data/lib/symmetric_encryption/version.rb +1 -1
  34. data/lib/symmetric_encryption/writer.rb +20 -13
  35. data/lib/symmetric_encryption.rb +13 -9
  36. metadata +10 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40e60b20cfaf40c1b3ad68fb05b12fd766886ac3d4527a02c8d456906e45b705
4
- data.tar.gz: 3c87cffcfc26fe8a057619b3559c3f93ff5a3951c219eb90deb1c2054ae4495f
3
+ metadata.gz: 17ec7e95cd640a1bc8b960bff9244557e3dcd58bb58744b054e4bb7ef95a051a
4
+ data.tar.gz: 36230ce36bf337f98d5cf70e45c5ed1658faeed8ce650cd9b4b7d12354a477df
5
5
  SHA512:
6
- metadata.gz: 479105df621736ea8ccaddc73129f4c6d9ebad8a6918a793044d9d3329f547e3a7cbd404719bcbd9918a5cedb0c18694f22173201e799ab70d3a8032a7a90ac6
7
- data.tar.gz: dd8fd1b290bc1e2e55311234e8a06660dbc6f0849382189bc9408432caa519f973a1cbb7835eb97805136699eaf357772531cb7dfe6dbe2a62c33b4600c141f5
6
+ metadata.gz: 4d880e284b3aa211e2a4bdeb872ff294d8c8743eb033edcafd6ec7ee569da3390b12821e555b1efe98503b2e4c4c05d0380f5da6d09577dfcd57badc12c0bce2
7
+ data.tar.gz: 36453ff31c896a7b7359b66cd53d3777f71b6855d53d8f002a77d7af91e3fe21c1a346869c0414aecbe8cc92c7e93dd73701edaa751072df6dcdd9459dd74752
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Symmetric Encryption
2
- ![](https://img.shields.io/gem/v/symmetric-encryption.svg) ![](https://img.shields.io/travis/rocketjob/symmetric-encryption.svg) ![](https://img.shields.io/gem/dt/symmetric-encryption.svg) ![](https://img.shields.io/badge/status-production%20ready-blue.svg)
2
+ [![Gem Version](https://img.shields.io/gem/v/symmetric-encryption.svg)](https://rubygems.org/gems/symmetric-encryption) [![Build Status](https://github.com/reidmorrison/symmetric-encryption/workflows/build/badge.svg)](https://github.com/reidmorrison/symmetric-encryption/actions?query=workflow%3Abuild) [![Downloads](https://img.shields.io/gem/dt/symmetric-encryption.svg)](https://rubygems.org/gems/symmetric-encryption) [![License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](http://opensource.org/licenses/Apache-2.0) ![](https://img.shields.io/badge/status-Production%20Ready-blue.svg)
3
3
 
4
- * http://github.com/rocketjob/symmetric-encryption
4
+ * https://encryption.rocketjob.io/
5
5
 
6
- Transparently encrypt ActiveRecord, Mongoid, and MongoMapper attributes. Encrypt passwords in configuration files. Encrypt entire files at rest.
6
+ Transparently encrypt ActiveRecord, and Mongoid attributes. Encrypt passwords in configuration files. Encrypt entire files at rest.
7
7
 
8
8
  ## Introduction
9
9
 
@@ -19,9 +19,7 @@ expose all the encryption algorithms supported by OpenSSL.
19
19
 
20
20
  ## Documentation
21
21
 
22
- [Symmetric Encryption Guide](http://rocketjob.github.io/symmetric-encryption)
23
-
24
- [Reference Documentation](http://www.rubydoc.info/gems/symmetric-encryption/)
22
+ [Symmetric Encryption Guide](https://encryption.rocketjob.io/)
25
23
 
26
24
  ## Rocket Job
27
25
 
@@ -168,7 +166,7 @@ may have backward compatibility issues:
168
166
 
169
167
  [Reid Morrison](https://github.com/reidmorrison)
170
168
 
171
- [Contributors](https://github.com/rocketjob/symmetric-encryption/graphs/contributors)
169
+ [Contributors](https://github.com/reidmorrison/symmetric-encryption/graphs/contributors)
172
170
 
173
171
  ## Versioning
174
172
 
data/Rakefile CHANGED
@@ -1,30 +1,30 @@
1
1
  # Setup bundler to avoid having to run bundle exec all the time.
2
- require 'rubygems'
3
- require 'bundler/setup'
2
+ require "rubygems"
3
+ require "bundler/setup"
4
4
 
5
- require 'rake/testtask'
6
- require_relative 'lib/symmetric_encryption/version'
5
+ require "rake/testtask"
6
+ require_relative "lib/symmetric_encryption/version"
7
7
 
8
8
  task :gem do
9
- system 'gem build symmetric-encryption.gemspec'
9
+ system "gem build symmetric-encryption.gemspec"
10
10
  end
11
11
 
12
12
  task publish: :gem do
13
13
  system "git tag -a v#{SymmetricEncryption::VERSION} -m 'Tagging #{SymmetricEncryption::VERSION}'"
14
- system 'git push --tags'
14
+ system "git push --tags"
15
15
  system "gem push symmetric-encryption-#{SymmetricEncryption::VERSION}.gem"
16
16
  system "rm symmetric-encryption-#{SymmetricEncryption::VERSION}.gem"
17
17
  end
18
18
 
19
19
  Rake::TestTask.new(:test) do |t|
20
- t.pattern = 'test/**/*_test.rb'
20
+ t.pattern = "test/**/*_test.rb"
21
21
  t.verbose = true
22
22
  t.warning = false
23
23
  end
24
24
 
25
25
  # By default run tests against all appraisals
26
- if !ENV['APPRAISAL_INITIALIZED'] && !ENV['TRAVIS']
27
- require 'appraisal'
26
+ if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"]
27
+ require "appraisal"
28
28
  task default: :appraisal
29
29
  else
30
30
  task default: :test
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'symmetric_encryption'
3
+ require "symmetric_encryption"
4
4
 
5
5
  SymmetricEncryption::CLI.run!(ARGV)
@@ -1 +1 @@
1
- require 'symmetric_encryption'
1
+ require "symmetric_encryption"
@@ -1,5 +1,5 @@
1
1
  module SymmetricEncryption
2
- module Railties
2
+ module ActiveRecord
3
3
  module AttrEncrypted
4
4
  def self.included(base)
5
5
  base.extend ClassMethods
@@ -39,7 +39,7 @@ module SymmetricEncryption
39
39
  # compression
40
40
  # Note: Adds a 6 byte header prior to encoding, only if :random_iv is false
41
41
  # Default: false
42
- def attr_encrypted(*params)
42
+ def attr_encrypted(*attributes, random_iv: nil, type: :string, compress: false)
43
43
  # Ensure ActiveRecord has created all its methods first
44
44
  # Ignore failures since the table may not yet actually exist
45
45
  begin
@@ -48,10 +48,21 @@ module SymmetricEncryption
48
48
  nil
49
49
  end
50
50
 
51
- options = params.last.is_a?(Hash) ? params.pop.dup : {}
51
+ random_iv = true if random_iv.nil? && SymmetricEncryption.randomize_iv?
52
52
 
53
- params.each do |attribute|
54
- SymmetricEncryption::Generator.generate_decrypted_accessors(self, attribute, "encrypted_#{attribute}", options)
53
+ if random_iv.nil?
54
+ warn("attr_encrypted() no longer allows a default value for option `random_iv`. Add `random_iv: false` if it is required.")
55
+ end
56
+
57
+ attributes.each do |attribute|
58
+ SymmetricEncryption::Generator.generate_decrypted_accessors(
59
+ self,
60
+ attribute,
61
+ "encrypted_#{attribute}",
62
+ random_iv: random_iv,
63
+ type: type,
64
+ compress: compress
65
+ )
55
66
  encrypted_attributes[attribute.to_sym] = "encrypted_#{attribute}".to_sym
56
67
  end
57
68
  end
@@ -0,0 +1,37 @@
1
+ module SymmetricEncryption
2
+ module ActiveRecord
3
+ class EncryptedAttribute < ::ActiveModel::Type::String
4
+ def initialize(random_iv: true, compress: false, type: :string)
5
+ @random_iv = random_iv
6
+ @compress = compress
7
+ @encrypted_type = type
8
+ end
9
+
10
+ def deserialize(value)
11
+ return if value.nil?
12
+
13
+ SymmetricEncryption.decrypt(value, type: encrypted_type)
14
+ end
15
+
16
+ def serialize(value)
17
+ return if value.nil?
18
+
19
+ SymmetricEncryption.encrypt(
20
+ value,
21
+ type: encrypted_type,
22
+ compress: compress,
23
+ random_iv: random_iv
24
+ )
25
+ end
26
+
27
+ private
28
+
29
+ # Symmetric Encryption uses coercible gem to handle casting
30
+ def cast_value(value)
31
+ value
32
+ end
33
+
34
+ attr_reader :random_iv, :compress, :encrypted_type
35
+ end
36
+ end
37
+ end
@@ -1,4 +1,4 @@
1
- require 'openssl'
1
+ require "openssl"
2
2
  module SymmetricEncryption
3
3
  # Hold all information related to encryption keys
4
4
  # as well as encrypt and decrypt data using those keys.
@@ -12,7 +12,7 @@ module SymmetricEncryption
12
12
  attr_writer :key
13
13
 
14
14
  # Returns [Cipher] from a cipher config instance.
15
- def self.from_config(cipher_name: 'aes-256-cbc',
15
+ def self.from_config(cipher_name: "aes-256-cbc",
16
16
  version: 0,
17
17
  always_add_header: true,
18
18
  encoding: :base64strict,
@@ -50,6 +50,8 @@ module SymmetricEncryption
50
50
  # This is the recommended format since newlines in the values to
51
51
  # SQL queries are cumbersome. Also the newline reformatting is unnecessary
52
52
  # It is not the default for backward compatibility
53
+ # :base64urlsafe
54
+ # Same as base64strict except that base64urlsafe uses '-' instead of '+' and '_' instead of '/'.
53
55
  # :base64
54
56
  # Return as a base64 encoded string
55
57
  # :base16
@@ -58,7 +60,7 @@ module SymmetricEncryption
58
60
  # Return as raw binary data string. Note: String can contain embedded nulls
59
61
  # Default: :base64strict
60
62
  #
61
- # version [Fixnum]
63
+ # version [Integer]
62
64
  # Optional. The version number of this encryption key
63
65
  # Used by SymmetricEncryption to select the correct key when decrypting data
64
66
  # Valid Range: 0..255
@@ -72,7 +74,7 @@ module SymmetricEncryption
72
74
  # Default: true
73
75
  def initialize(key:,
74
76
  iv: nil,
75
- cipher_name: 'aes-256-cbc',
77
+ cipher_name: "aes-256-cbc",
76
78
  version: 0,
77
79
  always_add_header: true,
78
80
  encoding: :base64strict)
@@ -84,7 +86,9 @@ module SymmetricEncryption
84
86
  @version = version.to_i
85
87
  @always_add_header = always_add_header
86
88
 
87
- raise(ArgumentError, "Cipher version has a valid range of 0 to 255. #{@version} is too high, or negative") if (@version > 255) || @version.negative?
89
+ return unless (@version > 255) || @version.negative?
90
+
91
+ raise(ArgumentError, "Cipher version has a valid range of 0 to 255. #{@version} is too high, or negative")
88
92
  end
89
93
 
90
94
  # Change the encoding
@@ -112,7 +116,7 @@ module SymmetricEncryption
112
116
  # to convert it to a string
113
117
  #
114
118
  # random_iv [true|false]
115
- # Whether the encypted value should use a random IV every time the
119
+ # Whether the encrypted value should use a random IV every time the
116
120
  # field is encrypted.
117
121
  # Notes:
118
122
  # * Setting random_iv to true will result in a different encrypted output for
@@ -131,7 +135,7 @@ module SymmetricEncryption
131
135
  # * Should only be used for large strings since compression overhead and
132
136
  # the overhead of adding the encryption header may exceed any benefits of
133
137
  # compression
134
- def encrypt(str, random_iv: false, compress: false, header: always_add_header)
138
+ def encrypt(str, random_iv: SymmetricEncryption.randomize_iv?, compress: false, header: always_add_header)
135
139
  return if str.nil?
136
140
 
137
141
  str = str.to_s
@@ -167,7 +171,9 @@ module SymmetricEncryption
167
171
  decrypted = binary_decrypt(decoded)
168
172
 
169
173
  # Try to force result to UTF-8 encoding, but if it is not valid, force it back to Binary
170
- decrypted.force_encoding(SymmetricEncryption::BINARY_ENCODING) unless decrypted.force_encoding(SymmetricEncryption::UTF8_ENCODING).valid_encoding?
174
+ unless decrypted.force_encoding(SymmetricEncryption::UTF8_ENCODING).valid_encoding?
175
+ decrypted.force_encoding(SymmetricEncryption::BINARY_ENCODING)
176
+ end
171
177
 
172
178
  decrypted
173
179
  end
@@ -180,7 +186,7 @@ module SymmetricEncryption
180
186
  #
181
187
  # Returned string is UTF8 encoded except for encoding :none
182
188
  def encode(binary_string)
183
- return binary_string if binary_string.nil? || (binary_string == '')
189
+ return binary_string if binary_string.nil? || (binary_string == "")
184
190
 
185
191
  encoder.encode(binary_string)
186
192
  end
@@ -190,7 +196,7 @@ module SymmetricEncryption
190
196
  #
191
197
  # Returned string is Binary encoded
192
198
  def decode(encoded_string)
193
- return encoded_string if encoded_string.nil? || (encoded_string == '')
199
+ return encoded_string if encoded_string.nil? || (encoded_string == "")
194
200
 
195
201
  encoder.decode(encoded_string)
196
202
  end
@@ -246,7 +252,7 @@ module SymmetricEncryption
246
252
  # Default: `always_add_header`
247
253
  #
248
254
  # See #encrypt to encrypt and encode the result as a string.
249
- def binary_encrypt(str, random_iv: false, compress: false, header: always_add_header)
255
+ def binary_encrypt(str, random_iv: SymmetricEncryption.randomize_iv?, compress: false, header: always_add_header)
250
256
  return if str.nil?
251
257
 
252
258
  string = str.to_s
@@ -316,8 +322,8 @@ module SymmetricEncryption
316
322
 
317
323
  openssl_cipher = ::OpenSSL::Cipher.new(header.cipher_name || cipher_name)
318
324
  openssl_cipher.decrypt
319
- openssl_cipher.key = header.key || @key
320
- if (iv = header.iv || @iv)
325
+ openssl_cipher.key = header.key || @key
326
+ if (iv = header.iv || @iv)
321
327
  openssl_cipher.iv = iv
322
328
  end
323
329
  result = openssl_cipher.update(data)
@@ -327,7 +333,7 @@ module SymmetricEncryption
327
333
 
328
334
  # Returns the magic header after applying the encoding in this cipher
329
335
  def encoded_magic_header
330
- @encoded_magic_header ||= encoder.encode(SymmetricEncryption::Header::MAGIC_HEADER).delete('=').strip
336
+ @encoded_magic_header ||= encoder.encode(SymmetricEncryption::Header::MAGIC_HEADER).delete("=").strip
331
337
  end
332
338
 
333
339
  # Returns [String] object represented as a string, filtering out the key
@@ -1,5 +1,5 @@
1
- require 'optparse'
2
- require 'fileutils'
1
+ require "optparse"
2
+ require "fileutils"
3
3
  module SymmetricEncryption
4
4
  class CLI
5
5
  attr_reader :key_path, :app_name, :encrypt, :config_file_path,
@@ -16,11 +16,11 @@ module SymmetricEncryption
16
16
 
17
17
  def initialize(argv)
18
18
  @version = current_version
19
- @environment = ENV['SYMMETRIC_ENCRYPTION_ENV'] || ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
20
- @config_file_path = File.expand_path(ENV['SYMMETRIC_ENCRYPTION_CONFIG'] || 'config/symmetric-encryption.yml')
21
- @app_name = 'symmetric-encryption'
19
+ @environment = ENV["SYMMETRIC_ENCRYPTION_ENV"] || ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development"
20
+ @config_file_path = File.expand_path(ENV["SYMMETRIC_ENCRYPTION_CONFIG"] || "config/symmetric-encryption.yml")
21
+ @app_name = "symmetric-encryption"
22
22
  @key_path = "#{ENV['HOME']}/.symmetric-encryption"
23
- @cipher_name = 'aes-256-cbc'
23
+ @cipher_name = "aes-256-cbc"
24
24
  @rolling_deploy = false
25
25
  @prompt = false
26
26
  @show_version = false
@@ -34,7 +34,7 @@ module SymmetricEncryption
34
34
  end
35
35
 
36
36
  def run!
37
- raise(ArgumentError, 'Cannot cleanup keys and rotate keys at the same time') if cleanup_keys && rotate_keys
37
+ raise(ArgumentError, "Cannot cleanup keys and rotate keys at the same time") if cleanup_keys && rotate_keys
38
38
 
39
39
  if show_version
40
40
  puts "Symmetric Encryption v#{VERSION}"
@@ -70,11 +70,11 @@ module SymmetricEncryption
70
70
  end
71
71
 
72
72
  def parser
73
- @parser ||= OptionParser.new do |opts|
73
+ @parser ||= OptionParser.new do |opts|
74
74
  opts.banner = <<~BANNER
75
75
  Symmetric Encryption v#{VERSION}
76
76
 
77
- For more information, see: https://rocketjob.github.io/symmetric-encryption/
77
+ For more information, see: https://encryption.rocketjob.io/
78
78
 
79
79
  Note:
80
80
  It is recommended to backup the current configuration file, or place it in version control before running
@@ -83,113 +83,129 @@ module SymmetricEncryption
83
83
  symmetric-encryption [options]
84
84
  BANNER
85
85
 
86
- opts.on '-e', '--encrypt [FILE_NAME]', 'Encrypt a file, or read from stdin if no file name is supplied.' do |file_name|
86
+ opts.on "-e", "--encrypt [FILE_NAME]", "Encrypt a file, or read from stdin if no file name is supplied." do |file_name|
87
87
  @encrypt = file_name || STDIN
88
88
  end
89
89
 
90
- opts.on '-d', '--decrypt [FILE_NAME]', 'Decrypt a file, or read from stdin if no file name is supplied.' do |file_name|
90
+ opts.on "-d", "--decrypt [FILE_NAME]", "Decrypt a file, or read from stdin if no file name is supplied." do |file_name|
91
91
  @decrypt = file_name || STDIN
92
92
  end
93
93
 
94
- opts.on '-o', '--output FILE_NAME', 'Write encrypted or decrypted file to this file, otherwise output goes to stdout.' do |file_name|
94
+ opts.on "-o", "--output FILE_NAME",
95
+ "Write encrypted or decrypted file to this file, otherwise output goes to stdout." do |file_name|
95
96
  @output_file_name = file_name
96
97
  end
97
98
 
98
- opts.on '-P', '--prompt', 'When encrypting or decrypting, prompt for a string encrypt or decrypt.' do
99
+ opts.on "-P", "--prompt", "When encrypting or decrypting, prompt for a string encrypt or decrypt." do
99
100
  @prompt = true
100
101
  end
101
102
 
102
- opts.on '-z', '--compress', 'Compress encrypted output file. [Default for encrypting files]' do
103
+ opts.on "-z", "--compress", "Compress encrypted output file. [Default for encrypting files]" do
103
104
  @compress = true
104
105
  end
105
106
 
106
- opts.on '-Z', '--no-compress', 'Does not compress the output file. [Default for encrypting strings]' do
107
+ opts.on "-Z", "--no-compress", "Does not compress the output file. [Default for encrypting strings]" do
107
108
  @compress = false
108
109
  end
109
110
 
110
- opts.on '-E', '--env ENVIRONMENT', "Environment to use in the config file. Default: SYMMETRIC_ENCRYPTION_ENV || RACK_ENV || RAILS_ENV || 'development'" do |environment|
111
+ opts.on "-E", "--env ENVIRONMENT",
112
+ "Environment to use in the config file. Default: SYMMETRIC_ENCRYPTION_ENV || RACK_ENV || RAILS_ENV || 'development'" do |environment|
111
113
  @environment = environment
112
114
  end
113
115
 
114
- opts.on '-c', '--config CONFIG_FILE_PATH', 'File name & path to the Symmetric Encryption configuration file. Default: config/symmetric-encryption.yml or Env var: `SYMMETRIC_ENCRYPTION_CONFIG`' do |path|
116
+ opts.on "-c", "--config CONFIG_FILE_PATH",
117
+ "File name & path to the Symmetric Encryption configuration file. Default: config/symmetric-encryption.yml or Env var: `SYMMETRIC_ENCRYPTION_CONFIG`" do |path|
115
118
  @config_file_path = path
116
119
  end
117
120
 
118
- opts.on '-m', '--migrate', 'Migrate configuration file to new format.' do
121
+ opts.on "-m", "--migrate", "Migrate configuration file to new format." do
119
122
  @migrate = true
120
123
  end
121
124
 
122
- opts.on '-r', '--re-encrypt [PATTERN]', 'ReEncrypt all files matching the pattern. Default: "**/*.{yml,rb}"' do |pattern|
123
- @re_encrypt = pattern || '**/*.{yml,rb}'
125
+ opts.on "-r", "--re-encrypt [PATTERN]",
126
+ 'ReEncrypt all files matching the pattern. Default: "**/*.{yml,rb}"' do |pattern|
127
+ @re_encrypt = pattern || "**/*.{yml,rb}"
124
128
  end
125
129
 
126
- opts.on '-n', '--new-password [SIZE]', 'Generate a new random password using only characters that are URL-safe base64. Default size is 22.' do |size|
130
+ opts.on "-n", "--new-password [SIZE]",
131
+ "Generate a new random password using only characters that are URL-safe base64. Default size is 22." do |size|
127
132
  @random_password = (size || 22).to_i
128
133
  end
129
134
 
130
- opts.on '-g', '--generate', 'Generate a new configuration file and encryption keys for every environment.' do |config|
135
+ opts.on "-g", "--generate", "Generate a new configuration file and encryption keys for every environment." do |config|
131
136
  @generate = config
132
137
  end
133
138
 
134
- opts.on '-s', '--keystore heroku|environment|file|aws|gcp', 'Which keystore to use during generation or re-encryption.' do |keystore|
135
- @keystore = (keystore || 'file').downcase.to_sym
139
+ opts.on "-s", "--keystore heroku|environment|file|aws|gcp",
140
+ "Which keystore to use during generation or re-encryption." do |keystore|
141
+ @keystore = (keystore || "file").downcase.to_sym
136
142
  end
137
143
 
138
- opts.on '-B', '--regions [us-east-1,us-east-2,us-west-1,us-west-2]', 'AWS KMS Regions to encrypt data key with.' do |regions|
139
- @regions = regions.to_s.split(',').collect(&:strip) if regions
144
+ opts.on "-B", "--regions [us-east-1,us-east-2,us-west-1,us-west-2]",
145
+ "AWS KMS Regions to encrypt data key with." do |regions|
146
+ @regions = regions.to_s.split(",").collect(&:strip) if regions
140
147
  end
141
148
 
142
- opts.on '-K', '--key-path KEY_PATH', 'Output path in which to write generated key files. Default: ~/.symmetric-encryption' do |path|
149
+ opts.on "-K", "--key-path KEY_PATH",
150
+ "Output path in which to write generated key files. Default: ~/.symmetric-encryption" do |path|
143
151
  @key_path = path
144
152
  end
145
153
 
146
- opts.on '-a', '--app-name NAME', 'Application name to use when generating a new configuration. Default: symmetric-encryption' do |name|
154
+ opts.on "-a", "--app-name NAME",
155
+ "Application name to use when generating a new configuration. Default: symmetric-encryption" do |name|
147
156
  @app_name = name
148
157
  end
149
158
 
150
- opts.on '-S', '--environments ENVIRONMENTS', 'Comma separated list of environments for which to generate the config file. Default: development,test,release,production' do |environments|
151
- @environments = environments.split(',').collect(&:strip).collect(&:to_sym)
159
+ opts.on "-S", "--environments ENVIRONMENTS",
160
+ "Comma separated list of environments for which to generate the config file. Default: development,test,release,production" do |environments|
161
+ @environments = environments.split(",").collect(&:strip).collect(&:to_sym)
152
162
  end
153
163
 
154
- opts.on '-C', '--cipher-name NAME', 'Name of the cipher to use when generating a new config file, or when rotating keys. Default: aes-256-cbc' do |name|
164
+ opts.on "-C", "--cipher-name NAME",
165
+ "Name of the cipher to use when generating a new config file, or when rotating keys. Default: aes-256-cbc" do |name|
155
166
  @cipher_name = name
156
167
  end
157
168
 
158
- opts.on '-R', '--rotate-keys', 'Generates a new encryption key version, encryption key files, and updates the configuration file.' do
169
+ opts.on "-R", "--rotate-keys",
170
+ "Generates a new encryption key version, encryption key files, and updates the configuration file." do
159
171
  @rotate_keys = true
160
172
  end
161
173
 
162
- opts.on '-U', '--rotate-kek', 'Replace the existing key encrypting keys only, the data encryption key is not changed, and updates the configuration file.' do
174
+ opts.on "-U", "--rotate-kek",
175
+ "Replace the existing key encrypting keys only, the data encryption key is not changed, and updates the configuration file." do
163
176
  @rotate_kek = true
164
177
  end
165
178
 
166
- opts.on '-D', '--rolling-deploy', 'During key rotation, support a rolling deploy by placing the new key second in the list so that it is not activated yet.' do
179
+ opts.on "-D", "--rolling-deploy",
180
+ "During key rotation, support a rolling deploy by placing the new key second in the list so that it is not activated yet." do
167
181
  @rolling_deploy = true
168
182
  end
169
183
 
170
- opts.on '-A', '--activate-key', 'Activates the key by moving the key with the highest version to the top.' do
184
+ opts.on "-A", "--activate-key", "Activates the key by moving the key with the highest version to the top." do
171
185
  @activate_key = true
172
186
  end
173
187
 
174
- opts.on '-X', '--cleanup-keys', 'Removes all encryption keys, except the one with the highest version from the configuration file.' do
188
+ opts.on "-X", "--cleanup-keys",
189
+ "Removes all encryption keys, except the one with the highest version from the configuration file." do
175
190
  @cleanup_keys = true
176
191
  end
177
192
 
178
- opts.on '-V', '--key-version NUMBER', 'Encryption key version to use when encrypting or re-encrypting. Default: (Current global version).' do |number|
193
+ opts.on "-V", "--key-version NUMBER",
194
+ "Encryption key version to use when encrypting or re-encrypting. Default: (Current global version)." do |number|
179
195
  @version = number.to_i
180
196
  end
181
197
 
182
- opts.on '-L', '--ciphers', 'List available OpenSSL ciphers.' do
198
+ opts.on "-L", "--ciphers", "List available OpenSSL ciphers." do
183
199
  puts "OpenSSL v#{OpenSSL::VERSION}. Available Ciphers:"
184
200
  puts OpenSSL::Cipher.ciphers.join("\n")
185
201
  exit
186
202
  end
187
203
 
188
- opts.on '-v', '--version', 'Display Symmetric Encryption version.' do
204
+ opts.on "-v", "--version", "Display Symmetric Encryption version." do
189
205
  @show_version = true
190
206
  end
191
207
 
192
- opts.on('-h', '--help', 'Prints this help.') do
208
+ opts.on("-h", "--help", "Prints this help.") do
193
209
  puts opts
194
210
  exit
195
211
  end
@@ -212,7 +228,7 @@ module SymmetricEncryption
212
228
 
213
229
  config_file_does_not_exist!
214
230
  self.environments ||= %i[development test release production]
215
- args = {
231
+ args = {
216
232
  app_name: app_name,
217
233
  environments: environments,
218
234
  cipher_name: cipher_name
@@ -237,7 +253,8 @@ module SymmetricEncryption
237
253
  end
238
254
 
239
255
  config = Config.read_file(config_file_path)
240
- SymmetricEncryption::Keystore.rotate_keys!(config, environments: environments || [], app_name: app_name, rolling_deploy: rolling_deploy, keystore: keystore)
256
+ SymmetricEncryption::Keystore.rotate_keys!(config, environments: environments || [], app_name: app_name,
257
+ rolling_deploy: rolling_deploy, keystore: keystore)
241
258
  Config.write_file(config_file_path, config)
242
259
  puts "Existing configuration file updated with new keys: #{config_file_path}"
243
260
  end
@@ -255,7 +272,7 @@ module SymmetricEncryption
255
272
  next if environments && !environments.include?(env.to_sym)
256
273
  next unless ciphers = cfg[:ciphers]
257
274
 
258
- highest = ciphers.max_by { |i| i[:version] }
275
+ highest = ciphers.max_by { |i| i[:version] }
259
276
  ciphers.clear
260
277
  ciphers << highest
261
278
  end
@@ -270,7 +287,7 @@ module SymmetricEncryption
270
287
  next if environments && !environments.include?(env.to_sym)
271
288
  next unless ciphers = cfg[:ciphers]
272
289
 
273
- highest = ciphers.max_by { |i| i[:version] }
290
+ highest = ciphers.max_by { |i| i[:version] }
274
291
  ciphers.delete(highest)
275
292
  ciphers.unshift(highest)
276
293
  end
@@ -280,7 +297,8 @@ module SymmetricEncryption
280
297
  end
281
298
 
282
299
  def encrypt_file(input_file_name)
283
- SymmetricEncryption::Writer.encrypt(source: input_file_name, target: output_file_name || STDOUT, compress: compress, version: version)
300
+ SymmetricEncryption::Writer.encrypt(source: input_file_name, target: output_file_name || STDOUT, compress: compress,
301
+ version: version)
284
302
  end
285
303
 
286
304
  def decrypt_file(input_file_name)
@@ -289,22 +307,22 @@ module SymmetricEncryption
289
307
 
290
308
  def decrypt_string
291
309
  begin
292
- require 'highline'
310
+ require "highline"
293
311
  rescue LoadError
294
312
  puts("\nPlease install gem highline before using the command line task to decrypt an entered string.\n gem install \"highline\"\n\n")
295
313
  exit(-2)
296
314
  end
297
315
 
298
- encrypted = HighLine.new.ask('Enter the value to decrypt:')
316
+ encrypted = HighLine.new.ask("Enter the value to decrypt:")
299
317
  text = SymmetricEncryption.cipher(version).decrypt(encrypted)
300
318
 
301
319
  puts("\n\nEncrypted: #{encrypted}")
302
- output_file_name ? File.open(output_file_name, 'wb') { |f| f << text } : puts("Decrypted: #{text}\n\n")
320
+ output_file_name ? File.open(output_file_name, "wb") { |f| f << text } : puts("Decrypted: #{text}\n\n")
303
321
  end
304
322
 
305
323
  def encrypt_string
306
324
  begin
307
- require 'highline'
325
+ require "highline"
308
326
  rescue LoadError
309
327
  puts("\nPlease install gem highline before using the command line task to encrypt an entered string.\n gem install \"highline\"\n\n")
310
328
  exit(-2)
@@ -313,14 +331,14 @@ module SymmetricEncryption
313
331
  value2 = 0
314
332
 
315
333
  while value1 != value2
316
- value1 = HighLine.new.ask('Enter the value to encrypt:') { |q| q.echo = '*' }
317
- value2 = HighLine.new.ask('Re-enter the value to encrypt:') { |q| q.echo = '*' }
334
+ value1 = HighLine.new.ask("Enter the value to encrypt:") { |q| q.echo = "*" }
335
+ value2 = HighLine.new.ask("Re-enter the value to encrypt:") { |q| q.echo = "*" }
318
336
 
319
- puts('Values do not match, please try again') if value1 != value2
337
+ puts("Values do not match, please try again") if value1 != value2
320
338
  end
321
339
  compress = false if compress.nil?
322
340
  encrypted = SymmetricEncryption.cipher(version).encrypt(value1, compress: compress)
323
- output_file_name ? File.open(output_file_name, 'wb') { |f| f << encrypted } : puts("\n\nEncrypted: #{encrypted}\n\n")
341
+ output_file_name ? File.open(output_file_name, "wb") { |f| f << encrypted } : puts("\n\nEncrypted: #{encrypted}\n\n")
324
342
  end
325
343
 
326
344
  def gen_random_password(size)
@@ -328,7 +346,7 @@ module SymmetricEncryption
328
346
  puts("\nGenerated Password: #{p}")
329
347
  encrypted = SymmetricEncryption.encrypt(p)
330
348
  puts("Encrypted: #{encrypted}\n\n")
331
- File.open(output_file_name, 'wb') { |f| f << encrypted } if output_file_name
349
+ File.open(output_file_name, "wb") { |f| f << encrypted } if output_file_name
332
350
  end
333
351
 
334
352
  def current_version
@@ -14,7 +14,7 @@ module SymmetricEncryption
14
14
  # Coerce given value into given type
15
15
  # Does not coerce json or yaml values
16
16
  def self.coerce(value, type, from_type = nil)
17
- return value if value.nil? || (value == '')
17
+ return value if value.nil? || (value == "")
18
18
 
19
19
  from_type ||= value.class
20
20
  case type
@@ -32,7 +32,7 @@ module SymmetricEncryption
32
32
  # Note: if the type is :string, then the value is returned as is, and the
33
33
  # coercible gem is not used at all.
34
34
  def self.coerce_from_string(value, type)
35
- return value if value.nil? || (value == '')
35
+ return value if value.nil? || (value == "")
36
36
 
37
37
  case type
38
38
  when :string
@@ -50,7 +50,7 @@ module SymmetricEncryption
50
50
  # Note: if the type is :string, and value is not nil, then #to_s is called
51
51
  # on the value and the coercible gem is not used at all.
52
52
  def self.coerce_to_string(value, type)
53
- return value if value.nil? || (value == '')
53
+ return value if value.nil? || (value == "")
54
54
 
55
55
  case type
56
56
  when :string