diffcrypt 0.3.3 → 0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/Gemfile +2 -2
- data/README.md +14 -3
- data/diffcrypt.gemspec +1 -1
- data/lib/diffcrypt/cli.rb +12 -9
- data/lib/diffcrypt/encryptor.rb +6 -5
- data/lib/diffcrypt/file.rb +48 -0
- data/lib/diffcrypt/rails/encrypted_configuration.rb +15 -4
- data/lib/diffcrypt/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e40a357c62cf93d9c49f336c7ad456d4f7510bd8389f3fb20c4913b91f4ef5f2
|
4
|
+
data.tar.gz: 4fb0296c2eaf901c59bdec117f974203500596f6347a9b8c12632b7dbe39ab77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d368c674a915b706b876a5a022c7003e3f7ecf30b38b581f2e7debf261d47102d759c27d317b85a71904bace22fd1a0306d9175b2c9496592375d786d3fe4fc1
|
7
|
+
data.tar.gz: 9e24c98075aab9c2f8e0550e757adea3df5b7f1e341f7d93d5644ee21e6a9ee9a352f7450a1a63afd609d876406c6efbe4aaff56e6c978c413259588625eedf5
|
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
+
## [0.4.0] - 2020-10-01
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
|
14
|
+
- Encryptor can now use other ciphers than the default
|
15
|
+
|
16
|
+
### Dependencies
|
17
|
+
|
18
|
+
- simplecov: 0.17.0 -> 0.18.0 (#20)
|
19
|
+
- rubocop: 0.88.0 -> 0.92.0 (#24)
|
20
|
+
|
21
|
+
|
22
|
+
|
10
23
|
## [0.3.3] - 2020-07-25
|
11
24
|
|
12
25
|
### Fixed
|
data/Gemfile
CHANGED
@@ -7,6 +7,6 @@ gemspec
|
|
7
7
|
|
8
8
|
gem 'minitest', '~> 5.0'
|
9
9
|
gem 'rake', '~> 13.0'
|
10
|
-
gem 'rubocop', '~> 0.
|
11
|
-
gem 'simplecov', '~> 0.
|
10
|
+
gem 'rubocop', '~> 0.92.0'
|
11
|
+
gem 'simplecov', '~> 0.19.0', require: false # CodeClimate not compatible with 0.18+ yet - https://github.com/codeclimate/test-reporter/issues/413
|
12
12
|
gem 'simplecov-lcov', '< 0.8'
|
data/README.md
CHANGED
@@ -36,8 +36,8 @@ There are a few ways to use the library, depending on how advanced your use case
|
|
36
36
|
The easiest way to get started is to use the CLI.
|
37
37
|
|
38
38
|
```shell
|
39
|
-
diffcrypt decrypt -k $(cat test/fixtures/
|
40
|
-
diffcrypt encrypt -k $(cat test/fixtures/
|
39
|
+
diffcrypt decrypt -k $(cat test/fixtures/aes-128-gcm.key) test/fixtures/example.yml.enc
|
40
|
+
diffcrypt encrypt -k $(cat test/fixtures/aes-128-gcm.key) test/fixtures/example.yml
|
41
41
|
```
|
42
42
|
|
43
43
|
|
@@ -69,7 +69,7 @@ the built in encrypter. All existing `rails credentials:edit` also work with thi
|
|
69
69
|
require 'diffcrypt/rails/encrypted_configuration'
|
70
70
|
module Rails
|
71
71
|
class Application
|
72
|
-
def encrypted(path, key_path: 'config/
|
72
|
+
def encrypted(path, key_path: 'config/aes-128-gcm.key', env_key: 'RAILS_MASTER_KEY')
|
73
73
|
Diffcrypt::Rails::EncryptedConfiguration.new(
|
74
74
|
config_path: Rails.root.join(path),
|
75
75
|
key_path: Rails.root.join(key_path),
|
@@ -83,6 +83,17 @@ end
|
|
83
83
|
|
84
84
|
|
85
85
|
|
86
|
+
## Converting between ciphers
|
87
|
+
|
88
|
+
Sometimes you may want to rotate the cipher used on a file. You cab do this rogramtically using the ruby code above, or you can also chain the CLI commands like so:
|
89
|
+
|
90
|
+
```shell
|
91
|
+
diffcrypt decrypt -k $(cat test/fixtures/aes-128-gcm.key) test/fixtures/example.yml.enc > test/fixtures/example.128.yml \
|
92
|
+
&& diffcrypt encrypt --cipher aes-256-gcm -k $(cat test/fixtures/aes-256-gcm.key) test/fixtures/example.128.yml > test/fixtures/example.256.yml.enc && rm test/fixtures/example.128.yml
|
93
|
+
```
|
94
|
+
|
95
|
+
|
96
|
+
|
86
97
|
## Development
|
87
98
|
|
88
99
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/diffcrypt.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
# Specify which files should be added to the gem when it is released.
|
24
24
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
|
-
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
25
|
+
spec.files = Dir.chdir(::File.expand_path(__dir__)) do
|
26
26
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
27
27
|
end
|
28
28
|
spec.bindir = 'bin'
|
data/lib/diffcrypt/cli.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative './encryptor'
|
4
|
+
require_relative './file'
|
4
5
|
require_relative './version'
|
5
6
|
|
6
7
|
module Diffcrypt
|
@@ -8,21 +9,22 @@ module Diffcrypt
|
|
8
9
|
desc 'decrypt <path>', 'Decrypt a file'
|
9
10
|
method_option :key, aliases: %i[k], required: true
|
10
11
|
def decrypt(path)
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
file = File.new(path)
|
13
|
+
ensure_file_exists(file)
|
14
|
+
say file.decrypt(key)
|
14
15
|
end
|
15
16
|
|
16
17
|
desc 'encrypt <path>', 'Encrypt a file'
|
17
18
|
method_option :key, aliases: %i[k], required: true
|
19
|
+
method_option :cipher, default: Encryptor::DEFAULT_CIPHER
|
18
20
|
def encrypt(path)
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
file = File.new(path)
|
22
|
+
ensure_file_exists(file)
|
23
|
+
say file.encrypt(key, cipher: options[:cipher])
|
22
24
|
end
|
23
25
|
|
24
26
|
desc 'generate-key', 'Generate a 32 bit key'
|
25
|
-
method_option :cipher, default: Encryptor::
|
27
|
+
method_option :cipher, default: Encryptor::DEFAULT_CIPHER
|
26
28
|
def generate_key
|
27
29
|
say Encryptor.generate_key(options[:cipher])
|
28
30
|
end
|
@@ -41,8 +43,9 @@ module Diffcrypt
|
|
41
43
|
@encryptor ||= Encryptor.new(key)
|
42
44
|
end
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
+
# @param [Diffcrypt::File] path
|
47
|
+
def ensure_file_exists(file)
|
48
|
+
abort('[ERROR] File does not exist') unless file.exists?
|
46
49
|
end
|
47
50
|
|
48
51
|
def self.exit_on_failure?
|
data/lib/diffcrypt/encryptor.rb
CHANGED
@@ -12,15 +12,16 @@ require_relative './version'
|
|
12
12
|
|
13
13
|
module Diffcrypt
|
14
14
|
class Encryptor
|
15
|
-
|
15
|
+
DEFAULT_CIPHER = 'aes-128-gcm'
|
16
16
|
|
17
|
-
def self.generate_key(cipher =
|
17
|
+
def self.generate_key(cipher = DEFAULT_CIPHER)
|
18
18
|
SecureRandom.hex(ActiveSupport::MessageEncryptor.key_len(cipher))
|
19
19
|
end
|
20
20
|
|
21
|
-
def initialize(key)
|
21
|
+
def initialize(key, cipher: DEFAULT_CIPHER)
|
22
22
|
@key = key
|
23
|
-
@
|
23
|
+
@cipher = cipher
|
24
|
+
@encryptor ||= ActiveSupport::MessageEncryptor.new([key].pack('H*'), cipher: cipher)
|
24
25
|
end
|
25
26
|
|
26
27
|
# @param [String] contents The raw YAML string to be encrypted
|
@@ -50,7 +51,7 @@ module Diffcrypt
|
|
50
51
|
data = encrypt_data contents, original_encrypted_contents
|
51
52
|
YAML.dump(
|
52
53
|
'client' => "diffcrypt-#{Diffcrypt::VERSION}",
|
53
|
-
'cipher' =>
|
54
|
+
'cipher' => @cipher,
|
54
55
|
'data' => data,
|
55
56
|
)
|
56
57
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './encryptor'
|
4
|
+
|
5
|
+
module Diffcrypt
|
6
|
+
class File
|
7
|
+
attr_reader :file
|
8
|
+
|
9
|
+
def initialize(path)
|
10
|
+
@path = ::File.absolute_path path
|
11
|
+
end
|
12
|
+
|
13
|
+
def encrypted?
|
14
|
+
to_yaml['cipher']
|
15
|
+
end
|
16
|
+
|
17
|
+
def cipher
|
18
|
+
to_yaml['cipher'] || Encryptor::DEFAULT_CIPHER
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Boolean]
|
22
|
+
def exists?
|
23
|
+
::File.exist?(@path)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [String] Raw contents of the file
|
27
|
+
def read
|
28
|
+
@read ||= ::File.read(@path)
|
29
|
+
end
|
30
|
+
|
31
|
+
def encrypt(key, cipher: DEFAULT_CIPHER)
|
32
|
+
return read if encrypted?
|
33
|
+
|
34
|
+
Encryptor.new(key, cipher: cipher).encrypt(read)
|
35
|
+
end
|
36
|
+
|
37
|
+
# TODO: Add a test to verify this does descrypt properly
|
38
|
+
def decrypt(key)
|
39
|
+
return read unless encrypted?
|
40
|
+
|
41
|
+
Encryptor.new(key, cipher: cipher).decrypt(read)
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_yaml
|
45
|
+
@to_yaml ||= YAML.safe_load(read)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -9,6 +9,8 @@ require 'active_support/core_ext/hash'
|
|
9
9
|
require 'active_support/core_ext/module/delegation'
|
10
10
|
require 'active_support/core_ext/object/inclusion'
|
11
11
|
|
12
|
+
require 'diffcrypt/file'
|
13
|
+
|
12
14
|
module Diffcrypt
|
13
15
|
module Rails
|
14
16
|
class EncryptedConfiguration
|
@@ -21,13 +23,13 @@ module Diffcrypt
|
|
21
23
|
delegate_missing_to :options
|
22
24
|
|
23
25
|
def initialize(config_path:, key_path:, env_key:, raise_if_missing_key:)
|
24
|
-
@content_path = Pathname.new(File.absolute_path(config_path)).yield_self do |path|
|
26
|
+
@content_path = Pathname.new(::File.absolute_path(config_path)).yield_self do |path|
|
25
27
|
path.symlink? ? path.realpath : path
|
26
28
|
end
|
29
|
+
@diffcrypt_file = Diffcrypt::File.new(@content_path)
|
27
30
|
@key_path = Pathname.new(key_path)
|
28
31
|
@env_key = env_key
|
29
32
|
@raise_if_missing_key = raise_if_missing_key
|
30
|
-
@active_support_encryptor = ActiveSupport::MessageEncryptor.new([key].pack('H*'), cipher: Encryptor::CIPHER)
|
31
33
|
end
|
32
34
|
|
33
35
|
# Determines if file is using the diffable format, or still
|
@@ -73,7 +75,7 @@ module Diffcrypt
|
|
73
75
|
# rubocop:disable Metrics/AbcSize
|
74
76
|
def writing(contents)
|
75
77
|
tmp_file = "#{Process.pid}.#{content_path.basename.to_s.chomp('.enc')}"
|
76
|
-
tmp_path = Pathname.new File.join(Dir.tmpdir, tmp_file)
|
78
|
+
tmp_path = Pathname.new ::File.join(Dir.tmpdir, tmp_file)
|
77
79
|
tmp_path.binwrite contents
|
78
80
|
|
79
81
|
yield tmp_path
|
@@ -103,9 +105,18 @@ module Diffcrypt
|
|
103
105
|
end
|
104
106
|
end
|
105
107
|
|
108
|
+
# Rails applications with an existing credentials file, the inbuilt active support encryptor should be used
|
109
|
+
# @return [ActiveSupport::MessageEncryptor]
|
110
|
+
def active_support_encryptor
|
111
|
+
@active_support_encryptor = ActiveSupport::MessageEncryptor.new(
|
112
|
+
[key].pack('H*'),
|
113
|
+
cipher: @diffcrypt_file.cipher,
|
114
|
+
)
|
115
|
+
end
|
116
|
+
|
106
117
|
# @return [Encryptor]
|
107
118
|
def encryptor
|
108
|
-
@encryptor ||= Encryptor.new key
|
119
|
+
@encryptor ||= Encryptor.new key, cipher: @diffcrypt_file.cipher
|
109
120
|
end
|
110
121
|
|
111
122
|
def read_env_key
|
data/lib/diffcrypt/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: diffcrypt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc Qualie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -70,8 +70,10 @@ files:
|
|
70
70
|
- lib/diffcrypt.rb
|
71
71
|
- lib/diffcrypt/cli.rb
|
72
72
|
- lib/diffcrypt/encryptor.rb
|
73
|
+
- lib/diffcrypt/file.rb
|
73
74
|
- lib/diffcrypt/rails/encrypted_configuration.rb
|
74
75
|
- lib/diffcrypt/version.rb
|
76
|
+
- tmp/.keep
|
75
77
|
homepage: https://github.com/marcqualie/diffcrypt
|
76
78
|
licenses:
|
77
79
|
- MIT
|
@@ -93,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
95
|
- !ruby/object:Gem::Version
|
94
96
|
version: '0'
|
95
97
|
requirements: []
|
96
|
-
rubygems_version: 3.
|
98
|
+
rubygems_version: 3.0.3
|
97
99
|
signing_key:
|
98
100
|
specification_version: 4
|
99
101
|
summary: Diffable encrypted configuration files
|