sym-crypt 1.0.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.
@@ -0,0 +1,31 @@
1
+ require 'sym/crypt/errors'
2
+ require 'base64'
3
+ require 'zlib'
4
+
5
+ module Sym
6
+ module Crypt
7
+ module Data
8
+ class Decoder
9
+ attr_accessor :data, :data_encoded, :data
10
+
11
+ def initialize(data_encoded, compress)
12
+ self.data_encoded = data_encoded
13
+ self.data = begin
14
+ Base64.urlsafe_decode64(data_encoded)
15
+ rescue
16
+ data_encoded
17
+ end
18
+
19
+ if compress.nil? || compress # auto-guess
20
+ self.data = begin
21
+ Zlib::Inflate.inflate(data)
22
+ rescue Zlib::Error => e
23
+ data
24
+ end
25
+ end
26
+ self.data = Marshal.load(data)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ require 'base64'
2
+ require 'zlib'
3
+
4
+ require 'sym/crypt/configuration'
5
+
6
+ module Sym
7
+ module Crypt
8
+ module Data
9
+ class Encoder
10
+ attr_accessor :data, :data_encoded
11
+
12
+ def initialize(data, compress)
13
+ self.data = data
14
+ self.data_encoded = Marshal.dump(data)
15
+ self.data_encoded = Zlib::Deflate.deflate(data_encoded, compression_level) if compress
16
+ self.data_encoded = Base64.urlsafe_encode64(data_encoded)
17
+ end
18
+
19
+ def compression_level
20
+ Sym::Crypt::Configuration.config.compression_level
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,44 @@
1
+ module Sym
2
+ module Crypt
3
+ module Data
4
+ class WrapperStruct < Struct.new(
5
+ :encrypted_data, # [Blob] Binary encrypted data (possibly compressed)
6
+ :iv, # [String] IV used to encrypt the data
7
+ :cipher_name, # [String] Name of the cipher used
8
+ :salt, # [Integer] For password-encrypted data this is the salt
9
+ :version, # [Integer] Version of the cipher used
10
+ :compress # [Boolean] indicates if compression should be applied
11
+ )
12
+
13
+ VERSION = 1
14
+
15
+ attr_accessor :compressed
16
+
17
+ def initialize(
18
+ encrypted_data:, # [Blob] Binary encrypted data (possibly compressed)
19
+ iv:, # [String] IV used to encrypt the data
20
+ cipher_name:, # [String] Name of the cipher used
21
+ salt: nil, # [Integer] For password-encrypted data this is the salt
22
+ version: VERSION, # [Integer] Version of the cipher used
23
+ compress: Sym::Crypt::Configuration.config.compression_enabled
24
+ )
25
+ super(encrypted_data, iv, cipher_name, salt, version, compress)
26
+ end
27
+
28
+ def config
29
+ Sym::Crypt::Configuration.config
30
+ end
31
+
32
+ def serialize
33
+ Marshal.dump(self)
34
+ end
35
+
36
+ def self.deserialize(data)
37
+ Marshal.load(data)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+
@@ -0,0 +1,14 @@
1
+ module Sym
2
+ module Crypt
3
+ # All public exceptions of this library are here.
4
+ module Errors
5
+ class Error < StandardError; end
6
+
7
+ class NoPasswordProvided < Sym::Crypt::Errors::Error; end
8
+
9
+ class NoPrivateKeyFound < Sym::Crypt::Errors::Error; end
10
+
11
+ class NoDataProvided < Sym::Crypt::Errors::Error; end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ require 'base64'
2
+ require 'sym/crypt/cipher_handler'
3
+
4
+ module Sym
5
+ module Crypt
6
+ module Extensions
7
+ module ClassMethods
8
+ def create_private_key
9
+ key = Sym::Crypt::NEW_CIPHER_PROC.call(Sym::Crypt::Configuration.property(:private_key_cipher)).random_key
10
+ ::Base64.urlsafe_encode64(key)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,123 @@
1
+ require 'sym/crypt'
2
+ require 'sym/crypt/data'
3
+ require 'sym/crypt/cipher_handler'
4
+ require 'openssl'
5
+ module Sym
6
+ module Crypt
7
+ module Extensions
8
+ # This is the module that is really included in your class
9
+ # when you include +Sym::Crypt+.
10
+ #
11
+ # The module provides easy access to the encryption configuration
12
+ # via the +#encryption_config+ method, as well as two key
13
+ # methods: +#encr+ and +#decr+.
14
+ #
15
+ # Methods +#encr_password+ and +#decr_password+ provide a good
16
+ # example of how this module can be extended to provide more uses
17
+ # of various ciphers, by calling into the private +_encr+ and +_decr+
18
+ # methods.f
19
+ module InstanceMethods
20
+ include Sym::Crypt::Data
21
+ include Sym::Crypt::CipherHandler
22
+
23
+ # Expects key to be a base64 encoded key
24
+ def encr(data, key, iv = nil)
25
+ raise Sym::Crypt::Errors::NoPrivateKeyFound unless key.present?
26
+ raise Sym::Crypt::Errors::NoDataProvided unless data.present?
27
+ encrypt_data(data, encryption_config.data_cipher, iv) do |cipher_struct|
28
+ cipher_struct.cipher.key = decode_key(key)
29
+ end
30
+ end
31
+
32
+ # Expects key to be a base64 encoded key
33
+ def decr(encrypted_data, key, iv = nil)
34
+ raise Sym::Crypt::Errors::NoPrivateKeyFound unless key.present?
35
+ raise Sym::Crypt::Errors::NoDataProvided unless encrypted_data.present?
36
+ decrypt_data(encrypted_data, encryption_config.data_cipher, iv) do |cipher_struct|
37
+ cipher_struct.cipher.key = decode_key(key)
38
+ end
39
+ end
40
+
41
+ def encr_password(data, password, iv = nil)
42
+ raise Sym::Crypt::Errors::NoDataProvided unless data.present?
43
+ raise Sym::Crypt::Errors::NoPasswordProvided unless password.present?
44
+ encrypt_data(data, encryption_config.password_cipher, iv) do |cipher_struct|
45
+ key, salt = make_password_key(cipher_struct.cipher, password)
46
+ cipher_struct.cipher.key = key
47
+ cipher_struct.salt = salt
48
+ end
49
+ end
50
+
51
+ def decr_password(encrypted_data, password, iv = nil)
52
+ raise Sym::Crypt::Errors::NoDataProvided unless encrypted_data.present?
53
+ raise Sym::Crypt::Errors::NoPasswordProvided unless password.present?
54
+ decrypt_data(encrypted_data, encryption_config.password_cipher, iv) do |cipher_struct|
55
+ key, = make_password_key(cipher_struct.cipher, password, cipher_struct.salt)
56
+ cipher_struct.cipher.key = key
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def encryption_config
63
+ Sym::Crypt::Configuration.config
64
+ end
65
+
66
+
67
+ def decode_key(encoded_key)
68
+ Base64.urlsafe_decode64(encoded_key)
69
+ rescue
70
+ encoded_key
71
+ end
72
+
73
+ def make_password_key(cipher, password, salt = nil)
74
+ key_len = cipher.key_len
75
+ salt ||= OpenSSL::Random.random_bytes 16
76
+ iter = 20000
77
+ digest = OpenSSL::Digest::SHA256.new
78
+ key = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iter, key_len, digest)
79
+ return key, salt
80
+ end
81
+
82
+ # Expects key to be a base64 encoded key data
83
+ def encrypt_data(data, cipher_name, iv = nil, &block)
84
+ data, compression_enabled = encode_incoming_data(data)
85
+ cipher_struct = create_cipher(direction: :encrypt,
86
+ cipher_name: cipher_name,
87
+ iv: iv)
88
+
89
+ block.call(cipher_struct) if block
90
+
91
+ encrypted_data = update_cipher(cipher_struct.cipher, data)
92
+ wrapper_struct = WrapperStruct.new(
93
+ encrypted_data: encrypted_data,
94
+ iv: cipher_struct.iv,
95
+ cipher_name: cipher_struct.cipher.name,
96
+ salt: cipher_struct.salt,
97
+ compress: !compression_enabled)
98
+ encode(wrapper_struct, false)
99
+ end
100
+
101
+ # Expects key to be a base64 encoded key data
102
+ def decrypt_data(encoded_data, cipher_name, iv = nil, &block)
103
+ wrapper_struct = decode(encoded_data)
104
+ cipher_struct = create_cipher(cipher_name: cipher_name,
105
+ iv: wrapper_struct.iv || iv,
106
+ direction: :decrypt,
107
+ salt: wrapper_struct.salt)
108
+ block.call(cipher_struct) if block
109
+ decode(update_cipher(cipher_struct.cipher, wrapper_struct.encrypted_data))
110
+ end
111
+
112
+
113
+ def encode_incoming_data(data)
114
+ compression_enabled = !data.respond_to?(:size) || (data.size > 100 && encryption_config.compression_enabled)
115
+ data = encode(data, compression_enabled)
116
+ [data, compression_enabled]
117
+ end
118
+
119
+ end
120
+ end
121
+ end
122
+ end
123
+
@@ -0,0 +1,17 @@
1
+ module Sym
2
+ module Crypt
3
+ VERSION = '1.0.0'
4
+ DESCRIPTION = <<-eof
5
+ sym-crypt is a core encryption module for the symmetric encryption app
6
+ (and a corresponding gem) "sym", and contains the main base serialization,
7
+ encryption, encoding, compression routines.
8
+
9
+ sym-crypt uses a symmetric 256-bit key with the AES-256-CBC cipher, which is the
10
+ same cipher as the one used by the US Government. For encyption with a
11
+ password sym-crypt uses AES-128-CBC cipher.
12
+
13
+ The resulting data is zlib-compressed and base64-encoded. The keys are also
14
+ base64 encoded for easy copying/pasting/etc.
15
+ eof
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sym/crypt/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'sym-crypt'
8
+ spec.version = Sym::Crypt::VERSION
9
+ spec.authors = ['Konstantin Gredeskoul']
10
+ spec.email = %w(kigster@gmail.com)
11
+
12
+ spec.summary = %q{Base encryption/decryption core of the encryption app Sym. If you need simple convenience wrappers around symmetric encryption provided by OpenSSL with sensible defaults, this gem is for you. If you require a CLI tool, please take a look at the gem 'sym'.}
13
+
14
+ spec.description = Sym::Crypt::DESCRIPTION
15
+
16
+ spec.homepage = 'https://github.com/kigster/sym-crypt'
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ spec.bindir = 'exe'
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ['lib']
22
+ spec.required_ruby_version = '>= 2.2'
23
+
24
+ #spec.add_dependency 'activesupport'
25
+ #spec.add_dependency 'highline', '~> 1.7'
26
+ #spec.add_dependency 'coin', '~> 0.1.8'
27
+ #spec.add_dependency 'dalli', '~> 2.7'
28
+
29
+ spec.add_development_dependency 'codeclimate-test-reporter', '~> 1.0'
30
+ spec.add_development_dependency 'simplecov'
31
+ spec.add_development_dependency 'irbtools'
32
+ spec.add_development_dependency 'bundler', '~> 1'
33
+ spec.add_development_dependency 'rake'
34
+ spec.add_development_dependency 'rspec', '~> 3'
35
+ spec.add_development_dependency 'rspec-its'
36
+ spec.add_development_dependency 'yard'
37
+ end
metadata ADDED
@@ -0,0 +1,189 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sym-crypt
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Konstantin Gredeskoul
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-07-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: codeclimate-test-reporter
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: simplecov
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: irbtools
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec-its
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: yard
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: "sym-crypt is a core encryption module for the symmetric encryption app
126
+ \n(and a corresponding gem) \"sym\", and contains the main base serialization, \nencryption,
127
+ encoding, compression routines.\n\nsym-crypt uses a symmetric 256-bit key with the
128
+ AES-256-CBC cipher, which is the \nsame cipher as the one used by the US Government.
129
+ For encyption with a \npassword sym-crypt uses AES-128-CBC cipher. \n\nThe resulting
130
+ data is zlib-compressed and base64-encoded. The keys are also \nbase64 encoded for
131
+ easy copying/pasting/etc.\n"
132
+ email:
133
+ - kigster@gmail.com
134
+ executables: []
135
+ extensions: []
136
+ extra_rdoc_files: []
137
+ files:
138
+ - ".codeclimate.yml"
139
+ - ".document"
140
+ - ".gitignore"
141
+ - ".rspec"
142
+ - ".rubocop.yml"
143
+ - ".travis.yml"
144
+ - ".yardopts"
145
+ - Gemfile
146
+ - LICENSE
147
+ - README.md
148
+ - Rakefile
149
+ - bin/console
150
+ - bin/setup
151
+ - lib/sym/crypt.rb
152
+ - lib/sym/crypt/cipher_handler.rb
153
+ - lib/sym/crypt/configuration.rb
154
+ - lib/sym/crypt/data.rb
155
+ - lib/sym/crypt/data/decoder.rb
156
+ - lib/sym/crypt/data/encoder.rb
157
+ - lib/sym/crypt/data/wrapper_struct.rb
158
+ - lib/sym/crypt/errors.rb
159
+ - lib/sym/crypt/extensions/class_methods.rb
160
+ - lib/sym/crypt/extensions/instance_methods.rb
161
+ - lib/sym/crypt/version.rb
162
+ - sym-crypt.gemspec
163
+ homepage: https://github.com/kigster/sym-crypt
164
+ licenses: []
165
+ metadata: {}
166
+ post_install_message:
167
+ rdoc_options: []
168
+ require_paths:
169
+ - lib
170
+ required_ruby_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '2.2'
175
+ required_rubygems_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ requirements: []
181
+ rubyforge_project:
182
+ rubygems_version: 2.6.11
183
+ signing_key:
184
+ specification_version: 4
185
+ summary: Base encryption/decryption core of the encryption app Sym. If you need simple
186
+ convenience wrappers around symmetric encryption provided by OpenSSL with sensible
187
+ defaults, this gem is for you. If you require a CLI tool, please take a look at
188
+ the gem 'sym'.
189
+ test_files: []