symmetric-encryption 3.9.1 → 4.0.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +72 -0
- data/bin/symmetric-encryption +5 -0
- data/lib/symmetric_encryption/cipher.rb +162 -419
- data/lib/symmetric_encryption/cli.rb +343 -0
- data/lib/symmetric_encryption/coerce.rb +5 -20
- data/lib/symmetric_encryption/config.rb +128 -50
- data/lib/symmetric_encryption/extensions/mongo_mapper/plugins/encrypted_key.rb +2 -2
- data/lib/symmetric_encryption/generator.rb +3 -2
- data/lib/symmetric_encryption/header.rb +260 -0
- data/lib/symmetric_encryption/key.rb +106 -0
- data/lib/symmetric_encryption/keystore/environment.rb +90 -0
- data/lib/symmetric_encryption/keystore/file.rb +102 -0
- data/lib/symmetric_encryption/keystore/memory.rb +53 -0
- data/lib/symmetric_encryption/keystore.rb +124 -0
- data/lib/symmetric_encryption/railtie.rb +5 -7
- data/lib/symmetric_encryption/reader.rb +74 -55
- data/lib/symmetric_encryption/rsa_key.rb +24 -0
- data/lib/symmetric_encryption/symmetric_encryption.rb +64 -102
- data/lib/symmetric_encryption/utils/re_encrypt_files.rb +140 -0
- data/lib/symmetric_encryption/version.rb +1 -1
- data/lib/symmetric_encryption/writer.rb +104 -117
- data/lib/symmetric_encryption.rb +9 -4
- data/test/active_record_test.rb +61 -40
- data/test/cipher_test.rb +179 -236
- data/test/config/symmetric-encryption.yml +140 -82
- data/test/header_test.rb +218 -0
- data/test/key_test.rb +231 -0
- data/test/keystore/environment_test.rb +119 -0
- data/test/keystore/file_test.rb +125 -0
- data/test/keystore_test.rb +59 -0
- data/test/mongoid_test.rb +13 -13
- data/test/reader_test.rb +52 -53
- data/test/symmetric_encryption_test.rb +50 -135
- data/test/test_db.sqlite3 +0 -0
- data/test/writer_test.rb +52 -31
- metadata +26 -14
- data/examples/symmetric-encryption.yml +0 -108
- data/lib/rails/generators/symmetric_encryption/config/config_generator.rb +0 -22
- data/lib/rails/generators/symmetric_encryption/config/templates/symmetric-encryption.yml +0 -50
- data/lib/rails/generators/symmetric_encryption/heroku_config/heroku_config_generator.rb +0 -20
- data/lib/rails/generators/symmetric_encryption/heroku_config/templates/symmetric-encryption.yml +0 -78
- data/lib/rails/generators/symmetric_encryption/new_keys/new_keys_generator.rb +0 -14
- data/lib/symmetric_encryption/key_encryption_key.rb +0 -32
- data/lib/symmetric_encryption/railties/symmetric_encryption.rake +0 -84
- data/lib/symmetric_encryption/utils/re_encrypt_config_files.rb +0 -82
data/lib/rails/generators/symmetric_encryption/heroku_config/templates/symmetric-encryption.yml
DELETED
@@ -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
|