symmetric-encryption 3.9.1 → 4.0.0.beta3

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +72 -0
  3. data/bin/symmetric-encryption +5 -0
  4. data/lib/symmetric_encryption/cipher.rb +162 -419
  5. data/lib/symmetric_encryption/cli.rb +343 -0
  6. data/lib/symmetric_encryption/coerce.rb +5 -20
  7. data/lib/symmetric_encryption/config.rb +128 -50
  8. data/lib/symmetric_encryption/extensions/mongo_mapper/plugins/encrypted_key.rb +2 -2
  9. data/lib/symmetric_encryption/generator.rb +3 -2
  10. data/lib/symmetric_encryption/header.rb +260 -0
  11. data/lib/symmetric_encryption/key.rb +106 -0
  12. data/lib/symmetric_encryption/keystore/environment.rb +90 -0
  13. data/lib/symmetric_encryption/keystore/file.rb +102 -0
  14. data/lib/symmetric_encryption/keystore/memory.rb +53 -0
  15. data/lib/symmetric_encryption/keystore.rb +124 -0
  16. data/lib/symmetric_encryption/railtie.rb +5 -7
  17. data/lib/symmetric_encryption/reader.rb +74 -55
  18. data/lib/symmetric_encryption/rsa_key.rb +24 -0
  19. data/lib/symmetric_encryption/symmetric_encryption.rb +64 -102
  20. data/lib/symmetric_encryption/utils/re_encrypt_files.rb +140 -0
  21. data/lib/symmetric_encryption/version.rb +1 -1
  22. data/lib/symmetric_encryption/writer.rb +104 -117
  23. data/lib/symmetric_encryption.rb +9 -4
  24. data/test/active_record_test.rb +61 -40
  25. data/test/cipher_test.rb +179 -236
  26. data/test/config/symmetric-encryption.yml +140 -82
  27. data/test/header_test.rb +218 -0
  28. data/test/key_test.rb +231 -0
  29. data/test/keystore/environment_test.rb +119 -0
  30. data/test/keystore/file_test.rb +125 -0
  31. data/test/keystore_test.rb +59 -0
  32. data/test/mongoid_test.rb +13 -13
  33. data/test/reader_test.rb +52 -53
  34. data/test/symmetric_encryption_test.rb +50 -135
  35. data/test/test_db.sqlite3 +0 -0
  36. data/test/writer_test.rb +52 -31
  37. metadata +26 -14
  38. data/examples/symmetric-encryption.yml +0 -108
  39. data/lib/rails/generators/symmetric_encryption/config/config_generator.rb +0 -22
  40. data/lib/rails/generators/symmetric_encryption/config/templates/symmetric-encryption.yml +0 -50
  41. data/lib/rails/generators/symmetric_encryption/heroku_config/heroku_config_generator.rb +0 -20
  42. data/lib/rails/generators/symmetric_encryption/heroku_config/templates/symmetric-encryption.yml +0 -78
  43. data/lib/rails/generators/symmetric_encryption/new_keys/new_keys_generator.rb +0 -14
  44. data/lib/symmetric_encryption/key_encryption_key.rb +0 -32
  45. data/lib/symmetric_encryption/railties/symmetric_encryption.rake +0 -84
  46. data/lib/symmetric_encryption/utils/re_encrypt_config_files.rb +0 -82
@@ -1,78 +0,0 @@
1
- #
2
- # Symmetric Encryption for Ruby
3
- #
4
- ---
5
- # For the development and test environments the test symmetric encryption keys
6
- # can be placed directly in the source code.
7
- # And therefore no key encryption key is required
8
- development: &development_defaults
9
- key: 1234567890ABCDEF
10
- iv: 1234567890ABCDEF
11
- cipher_name: aes-128-cbc
12
- encoding: :base64strict
13
-
14
- test:
15
- <<: *development_defaults
16
-
17
- <%
18
- rsa_key = SymmetricEncryption::KeyEncryptionKey.generate
19
- cipher_conf = SymmetricEncryption::Cipher.generate_random_keys(private_rsa_key: rsa_key, encrypted_key: '', encrypted_iv: '')
20
- cipher_name = cipher_conf[:cipher_name]
21
- encrypted_iv = cipher_conf[:encrypted_iv]
22
- encrypted_key = cipher_conf[:encrypted_key]
23
-
24
- puts "\n\n********************************************************************************"
25
- puts "Add the release environment key to Heroku: (Optional)\n\n"
26
- puts " heroku config:add RELEASE_KEY1=#{encrypted_key}\n\n"
27
- puts "\n\n********************************************************************************"
28
- puts "Add the release environment key to Heroku: (Optional)\n\n"
29
- puts " heroku config:add RELEASE_IV1=#{encrypted_iv}\n\n"
30
- -%>
31
- release:
32
- # Key encryption key
33
- # Key used to secure the encryption key when it is stored in a file or encrypted.
34
- private_rsa_key: |
35
- <%= rsa_key.each_line.collect { |line| " #{line}" }.join('') %>
36
-
37
- # List Symmetric Key files in the order of current / latest first
38
- ciphers:
39
- -
40
- # Filename containing Symmetric Encryption Key encrypted using the
41
- # key encryption key above (private_rsa_key).
42
- encrypted_key: "<%= '<' + "%= ENV['RELEASE_KEY1'] %" + '>' %>"
43
- encrypted_iv: "<%= '<' + "%= ENV['RELEASE_IV1'] %" + '>' %>"
44
- cipher_name: <%= cipher_name %>
45
- encoding: :base64strict
46
- version: 1
47
- always_add_header: true
48
-
49
- <%
50
- rsa_key = SymmetricEncryption::KeyEncryptionKey.generate
51
- cipher_conf = SymmetricEncryption::Cipher.generate_random_keys(private_rsa_key: rsa_key, encrypted_key: '', encrypted_iv: '')
52
- cipher_name = cipher_conf[:cipher_name]
53
- encrypted_iv = cipher_conf[:encrypted_iv]
54
- encrypted_key = cipher_conf[:encrypted_key]
55
-
56
- puts "Add the production key to Heroku:\n\n"
57
- puts " heroku config:add PRODUCTION_KEY1=#{encrypted_key}\n\n"
58
- puts "********************************************************************************\n\n\n"
59
- puts "Add the production key to Heroku:\n\n"
60
- puts " heroku config:add PRODUCTION_IV1=#{encrypted_iv}\n\n"
61
- puts "********************************************************************************\n\n\n"
62
- -%>
63
- production:
64
- # Since the encryption key must NOT be stored along with the
65
- # source code, only store the key encryption key here.
66
- private_rsa_key: |
67
- <%= rsa_key.each_line.collect { |line| " #{line}" }.join('') %>
68
-
69
- # List Symmetric Key files in the order of current / latest first
70
- ciphers:
71
- -
72
- # Encrypted key is supplied via an environment variable.
73
- encrypted_key: "<%= '<' + "%= ENV['PRODUCTION_KEY1'] %" + '>' %>"
74
- encrypted_iv: "<%= '<' + "%= ENV['PRODUCTION_IV1'] %" + '>' %>"
75
- cipher_name: <%= cipher_name %>
76
- encoding: :base64strict
77
- version: 1
78
- always_add_header: true
@@ -1,14 +0,0 @@
1
- module SymmetricEncryption
2
- module Generators
3
- class NewKeysGenerator < Rails::Generators::Base
4
- desc 'Generate new Symmetric key and initialization vector based on values in config/symmetric-encryption.yml'
5
-
6
- argument :environment, type: :string, optional: false
7
-
8
- def create_config_file
9
- SymmetricEncryption.generate_symmetric_key_files(File.join('config', 'symmetric-encryption.yml'), environment)
10
- end
11
-
12
- end
13
- end
14
- end
@@ -1,32 +0,0 @@
1
- require 'openssl'
2
- module SymmetricEncryption
3
- # Class that manages the key that is used to encrypt the encryption key.
4
- # Currently uses RSA asymmetric encryption to secure the key.
5
- #
6
- # Note:
7
- # No encoding or decoding is performed.
8
- class KeyEncryptionKey
9
- # Returns [String] a new key encryption key.
10
- def self.generate(options = {})
11
- options = options.dup
12
- size = options.delete(:size) || 2048
13
- OpenSSL::PKey::RSA.generate(size).to_s
14
- end
15
-
16
- def initialize(key_encryption_key)
17
- @rsa = OpenSSL::PKey::RSA.new(key_encryption_key)
18
- end
19
-
20
- def encrypt(key)
21
- rsa.public_encrypt(key)
22
- end
23
-
24
- def decrypt(encrypted_key)
25
- rsa.private_decrypt(encrypted_key)
26
- end
27
-
28
- private
29
-
30
- attr_reader :rsa
31
- end
32
- end
@@ -1,84 +0,0 @@
1
- namespace :symmetric_encryption do
2
-
3
- desc 'Decrypt the supplied string. Example: VALUE="_encrypted_string_" rake symmetric_encryption:decrypt'
4
- task :decrypt => :environment do
5
- puts "\nEncrypted: #{ENV['VALUE']}"
6
- puts "Decrypted: #{SymmetricEncryption.decrypt(ENV['VALUE'])}\n\n"
7
- end
8
-
9
- desc 'Encrypt a value, such as a password. Example: rake symmetric_encryption:encrypt'
10
- task :encrypt => :environment do
11
- begin
12
- require 'highline'
13
- rescue LoadError
14
- raise(SymmetricEncryption::ConfigError, "Please install gem highline before using the command line task to encrypt an entered string.\n gem install \"highline\"")
15
- end
16
- password1 = nil
17
- password2 = 0
18
-
19
- while password1 != password2
20
- password1 = HighLine.new.ask('Enter the value to encrypt:') { |q| q.echo = '*' }
21
- password2 = HighLine.new.ask('Re-enter the value to encrypt:') { |q| q.echo = '*' }
22
-
23
- if (password1 != password2)
24
- puts 'Passwords do not match, please try again'
25
- end
26
- end
27
- puts "\nEncrypted: #{SymmetricEncryption.encrypt(password1)}\n\n"
28
- end
29
-
30
- desc 'Generate a random password and display its encrypted form. Example: rake symmetric_encryption:random_password'
31
- task :random_password => :environment do
32
- p = SymmetricEncryption.random_password
33
- puts "\nGenerated Password: #{p}"
34
- puts "Encrypted: #{SymmetricEncryption.encrypt(p)}\n\n"
35
- end
36
-
37
- desc 'Decrypt a file. Example: INFILE="encrypted_filename" OUTFILE="filename" rake symmetric_encryption:decrypt_file'
38
- task :decrypt_file => :environment do
39
- input_filename = ENV['INFILE']
40
- output_filename = ENV['OUTFILE']
41
- block_size = ENV['BLOCKSIZE'] || 65535
42
-
43
- if input_filename && output_filename
44
- puts "\nDecrypting file: #{input_filename} and writing to: #{output_filename}\n\n"
45
- ::File.open(output_filename, 'wb') do |output_file|
46
- SymmetricEncryption::Reader.open(input_filename) do |input_file|
47
- while !input_file.eof?
48
- output_file.write(input_file.read(block_size))
49
- end
50
- end
51
- end
52
- puts "\n#{output_filename} now contains the decrypted contents of #{input_filename}\n\n"
53
- else
54
- puts 'Missing input and/or output filename. Usage:'
55
- puts ' INFILE="encrypted_filename" OUTFILE="filename" rake symmetric_encryption:decrypt_file'
56
- end
57
- end
58
-
59
- desc 'Encrypt a file. Example: INFILE="filename" OUTFILE="encrypted_filename" rake symmetric_encryption:encrypt_file'
60
- task :encrypt_file => :environment do
61
- input_filename = ENV['INFILE']
62
- output_filename = ENV['OUTFILE']
63
- compress = (ENV['COMPRESS'] != nil)
64
- block_size = ENV['BLOCKSIZE'] || 65535
65
-
66
- if input_filename && output_filename
67
- puts "\nEncrypting file: #{input_filename} and writing to: #{output_filename}\n\n"
68
- ::File.open(input_filename, 'rb') do |input_file|
69
- SymmetricEncryption::Writer.open(output_filename, compress: compress) do |output_file|
70
- while !input_file.eof?
71
- output_file.write(input_file.read(block_size))
72
- end
73
- end
74
- end
75
- puts "\n#{output_filename} now contains the encrypted #{"and compressed " if compress}contents of #{input_filename}\n\n"
76
- else
77
- puts 'Missing input and/or output filename. Usage:'
78
- puts ' INFILE="filename" OUTFILE="encrypted_filename" rake symmetric_encryption:encrypt_file'
79
- puts 'To compress the file before encrypting:'
80
- puts ' COMPRESS=1 INFILE="filename" OUTFILE="encrypted_filename" rake symmetric_encryption:encrypt_file'
81
- end
82
- end
83
-
84
- end
@@ -1,82 +0,0 @@
1
- # Used for re-encrypting encrypted passwords stored in configuration files.
2
- #
3
- # Search for `SymmetricEncryption.try_decrypt` in config files and replace the
4
- # encrypted value with one encrypted using the new encryption key.
5
- #
6
- # Example:
7
- # re_encrypt = SymmetricEncryption::Utils::ReEncryptConfigFiles.new(version: 4)
8
- # re_encrypt.process_directory('../../**/*.yml')
9
- module SymmetricEncryption
10
- module Utils
11
- class ReEncryptConfigFiles
12
- DEFAULT_REGEXP = /\A(.*)SymmetricEncryption.try_decrypt[\s\(\"\'].([\w@=+\/\\]+)[\'\"](.*)\Z/
13
-
14
- attr_accessor :cipher, :path, :search_regexp
15
-
16
- # Parameters:
17
- # version: [Integer]
18
- # Version of the encryption key to use when re-encrypting the value.
19
- # Default: Default cipher ( first in the list of configured ciphers )
20
- def initialize(params={})
21
- params = params.dup
22
- version = params.delete(:version)
23
- @path = params.delete(:path)
24
- @search_regexp = params.delete(:search_regexp) || DEFAULT_REGEXP
25
- @cipher = SymmetricEncryption.cipher(version)
26
- raise(ArgumentError, "Undefined encryption key version: #{version}") if @cipher.nil?
27
- raise(ArgumentError, "Unknown parameters: #{params.inspect}") if params.size > 0
28
- end
29
-
30
- # Re-encrypt the supplied enctrypted value with the new cipher
31
- def re_encrypt(encrypted)
32
- if unencrypted = SymmetricEncryption.try_decrypt(encrypted)
33
- cipher.encrypt(unencrypted)
34
- else
35
- encrypted
36
- end
37
- end
38
-
39
- # Process a single file.
40
- #
41
- # Returns [true|false] whether the file was modified
42
- def process_file(file_name)
43
- match = false
44
- lines = File.read(file_name)
45
- output_lines = ''
46
- lines.each_line do |line|
47
- if result = line.match(search_regexp)
48
- before_str = result[1]
49
- encrypted = result[2]
50
- after_str = result[3]
51
- after_str = after_str[1..-1] if after_str.starts_with?(')')
52
- new_value = re_encrypt(encrypted)
53
- if new_value != encrypted
54
- match = true
55
- output_lines << "#{before_str}SymmetricEncryption.try_decrypt('#{new_value}')#{after_str}\n"
56
- else
57
- output_lines << line
58
- end
59
- else
60
- output_lines << line
61
- end
62
- end
63
- if match
64
- File.open(file_name, 'wb') { |file| file.write(output_lines) }
65
- end
66
- match
67
- end
68
-
69
- # Process a directory of files.
70
- #
71
- # Parameters:
72
- # path: [String]
73
- # Search path to look for files in.
74
- # Example: '../../**/*.yml'
75
- def process_directory(path)
76
- Dir[path].each do |file_name|
77
- process_file(file_name)
78
- end
79
- end
80
- end
81
- end
82
- end