sekret 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ad0d96047fe97b5ec72912cf378904b8a469335a27e43e89b1581ce89e1b1c54
4
+ data.tar.gz: 6227fc843e7e64144e7317b4d0722942569f9b2fff3f4c488fd0add2d896cca8
5
+ SHA512:
6
+ metadata.gz: faf6946b2a53332e95ccf529e4ec4f7a838c33edbba16218ea66ab437f762a1647ae0c0d7f6f89b3f5909604d0016fd43bdc0a4164f0493be981d2897bd86b67
7
+ data.tar.gz: 4cd9b9230f599cc15b3a5811cb42b1661632251031dfec629e501975c5a1bed6b7d419a2186ef069495e478e2ec8e5e0d5f1fb8b0914e9ae7e3cd3c161203377
@@ -0,0 +1,30 @@
1
+ # Sekret
2
+
3
+
4
+ ### Getting Setup
5
+
6
+ There are a few config options.
7
+
8
+ ```ruby
9
+ Sekret.configure do |config|
10
+ config.mac_sekret = 'Super Sekret'
11
+ config.public_key = File.read('path to public pem')
12
+ config.private_key = File.read('path to private pem')
13
+ end
14
+ ```
15
+
16
+ ### Encrypt Data
17
+
18
+ ```ruby
19
+ Sekret.encrypt('This is my secret message')
20
+
21
+ # => 'abc.123'
22
+ ```
23
+
24
+ ### Decrypt Data
25
+
26
+ ```ruby
27
+ Sekret.decrypt('abc.123')
28
+
29
+ # => 'This is my secret message'
30
+ ```
@@ -0,0 +1,19 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'yard'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task default: :spec
8
+
9
+ namespace :docs do
10
+ desc 'Generate docs'
11
+ task :generate do
12
+ YARD::CLI::Yardoc.run
13
+ end
14
+
15
+ desc 'Get docs stats'
16
+ task :stats do
17
+ YARD::CLI::Stats.run('--list-undoc')
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ require 'sekret/configuration'
2
+ require 'sekret/decryptor'
3
+ require 'sekret/encryptor'
4
+ require 'sekret/errors'
5
+ require 'sekret/key_generator'
6
+ require 'sekret/version'
7
+
8
+ ##
9
+ # Used for encrypting/decrypting data
10
+ module Sekret
11
+ ##
12
+ # Encrypt the passed payload
13
+ #
14
+ # @param payload [String] The plaintext to encrypt
15
+ #
16
+ # @return [String] The encrypted payload
17
+ def self.encrypt(payload)
18
+ Sekret::Encryptor.new(Sekret.config.private_key, payload).call
19
+ end
20
+
21
+ ##
22
+ # Decrypt the passed payload
23
+ #
24
+ # @param message [String] the encrypted message to decrypt
25
+ #
26
+ # @return [String] The un-encrypted payload
27
+ def self.decrypt(message)
28
+ Sekret::Decryptor.new(Sekret.config.public_key, message).call
29
+ end
30
+ end
@@ -0,0 +1,87 @@
1
+ require 'openssl'
2
+
3
+ require_relative 'checksum'
4
+ require_relative 'configuration'
5
+ require_relative 'errors'
6
+
7
+ module Sekret
8
+ ##
9
+ # Performs the AES encryption on the message body
10
+ #
11
+ # @author Maddie Schipper
12
+ # @since 1.0.0
13
+ #
14
+ # @private
15
+ class BodyEncryption
16
+ ##
17
+ # The algorithm used for encryption/decryption
18
+ ALGORITHM = 'AES-256-CBC'.freeze
19
+
20
+ class << self
21
+ ##
22
+ # The result of the encryption
23
+ #
24
+ # @attr key [String] The random key used for encryption
25
+ # @attr iv [String] The random iv used for encryption
26
+ # @attr checksum [String] The HMAC-SHA256 of the encrypted body
27
+ # @attr body [String] The encrypted body
28
+ Result = Struct.new(:key, :iv, :checksum, :body)
29
+
30
+ ##
31
+ # Encrypt a payload using a random key and iv
32
+ #
33
+ # @param plaintext [String] The payload to encrypt
34
+ #
35
+ # @return [Result]
36
+ def encrypt(plaintext)
37
+ key = OpenSSL::Cipher.new(ALGORITHM).random_key
38
+ iv = OpenSSL::Cipher.new(ALGORITHM).random_iv
39
+ aes = OpenSSL::Cipher.new(ALGORITHM)
40
+ aes.encrypt
41
+ aes.key = key
42
+ aes.iv = iv
43
+ cipher = aes.update(plaintext)
44
+ cipher << aes.final
45
+ digest = generate_digest(cipher)
46
+ Result.new(key, iv, digest, cipher)
47
+ end
48
+
49
+ ##
50
+ # Decrypt the payload
51
+ #
52
+ # @param header [Header] The header that contains the key, iv, & checksum
53
+ # @param encrypted [String] The encrypted content
54
+ #
55
+ # @return [String] The un-encrypted message
56
+ def decrypt(header, encrypted)
57
+ validate_checksum!(header.authenticity, encrypted)
58
+ aes = OpenSSL::Cipher.new(ALGORITHM)
59
+ aes.decrypt
60
+ aes.key = header.key
61
+ aes.iv = header.iv
62
+ plaintext = aes.update(encrypted)
63
+ plaintext << aes.final
64
+ plaintext
65
+ end
66
+
67
+ private
68
+
69
+ def generate_digest(body)
70
+ return nil if Sekret.config.mac_secret.nil?
71
+ Checksum.hmac_sha256(Sekret.config.mac_secret, body)
72
+ end
73
+
74
+ def validate_checksum!(checksum, body)
75
+ return if checksum.nil?
76
+ if Sekret.config.mac_secret.nil?
77
+ raise Sekret::Errors::MissingMacSecretError,
78
+ 'The encrypted message contains an authenticity. But Sekret doesn\'t have a mac_secret'
79
+ end
80
+ digest = Checksum.hmac_sha256(Sekret.config.mac_secret, body)
81
+ if digest != checksum
82
+ raise Sekret::Errors::MissmatchedMacError, 'The message authenticity doesn\'t match.'
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,25 @@
1
+ require 'openssl'
2
+
3
+ module Sekret
4
+ ##
5
+ # Checksum raw data
6
+ #
7
+ # @author Maddie Schipper
8
+ # @since 1.0.0
9
+ #
10
+ # @private
11
+ class Checksum
12
+ class << self
13
+ ##
14
+ # Create a HMAC-SHA256 of a playload
15
+ #
16
+ # @param key [String] The key for the hash
17
+ # @param payload [String] The payload to hash
18
+ #
19
+ # @return [String] The HMAC-SHA256
20
+ def hmac_sha256(key, payload)
21
+ OpenSSL::HMAC.hexdigest('SHA256', key, payload)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'cli/runner'
2
+
3
+ module Sekret
4
+ ##
5
+ # CLI Interface for Sekret
6
+ #
7
+ # @private
8
+ module CLI
9
+ ##
10
+ # Run the CLI
11
+ #
12
+ # @param args [Array<String>] An array of arguments
13
+ def self.run(args)
14
+ Sekret::CLI::Runner.new(args).call
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,10 @@
1
+ Sekret Help
2
+
3
+ Sekret Version: <%= Sekret::VERSION %>
4
+
5
+ Commands:
6
+
7
+ generate-keys Create a new set of public & private keys
8
+ Will be printed to stdout
9
+ version Print the version number
10
+ help Print this message
@@ -0,0 +1,69 @@
1
+ require 'erb'
2
+ require 'pathname'
3
+
4
+ module Sekret
5
+ module CLI
6
+ ##
7
+ # The class that handle the CLI
8
+ #
9
+ # @author Maddie Schipper
10
+ # @since 1.0.0
11
+ #
12
+ # @private
13
+ class Runner
14
+ ##
15
+ # The arguments left after parsing options
16
+ #
17
+ # @return [Array<String>]
18
+ attr_reader :args
19
+
20
+ ##
21
+ # Create a new runner instance
22
+ #
23
+ # @param args [Array<String>] The CLI arguments
24
+ def initialize(args)
25
+ @args = args
26
+ end
27
+
28
+ ##
29
+ # Perform the CLI call
30
+ def call
31
+ command = args.shift
32
+ case command
33
+ when 'generate-keys'
34
+ perform_generate_keys
35
+ when 'help'
36
+ print_help
37
+ when 'version'
38
+ print_version
39
+ else
40
+ raise "Unknown Command #{command}. Try `sekret help`"
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def perform_generate_keys
47
+ keys = Sekret::KeyGenerator.generate_rsa_keys
48
+ puts <<~EOF
49
+ Generated new keys:
50
+ Private Key
51
+ #{keys.private_key}
52
+ Public Key
53
+ #{keys.public_key}
54
+ EOF
55
+ end
56
+
57
+ def print_help
58
+ path = ::Pathname.new(__dir__).join('help.txt.erb')
59
+ content = File.read(path)
60
+ template = ERB.new(content)
61
+ STDOUT.puts(template.result)
62
+ end
63
+
64
+ def print_version
65
+ STDOUT.puts(Sekret::VERSION)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,31 @@
1
+ module Sekret
2
+ ##
3
+ # The configuration object
4
+ #
5
+ # @attr mac_secret [String] A random secret that will be used to generate the encryption checksum.
6
+ # @attr private_key [String] A RSA private key in pem format.
7
+ # @attr public_key [String] A RSA public key in pem format.
8
+ Configuration = Struct.new(:mac_secret, :private_key, :public_key)
9
+
10
+ ##
11
+ # The config lock
12
+ CONFIG_MUTEX = Mutex.new
13
+
14
+ ##
15
+ # Retuns a new config
16
+ #
17
+ # @return [Configuration]
18
+ #
19
+ # @private
20
+ def self.config
21
+ CONFIG_MUTEX.synchronize do
22
+ @config ||= Configuration.new(nil, nil, nil)
23
+ end
24
+ end
25
+
26
+ ##
27
+ # Configuration
28
+ def self.configure
29
+ yield config
30
+ end
31
+ end
@@ -0,0 +1,64 @@
1
+ require 'openssl'
2
+
3
+ require_relative 'encoder'
4
+ require_relative 'body_encryption'
5
+ require_relative 'errors'
6
+
7
+ module Sekret
8
+ ##
9
+ # Handles decrypting a message
10
+ #
11
+ # @author Maddie Schipper
12
+ # @since 1.0.0
13
+ class Decryptor
14
+ ##
15
+ # An intermediate representation of the decrypted message
16
+ #
17
+ # @attr header [String] The encrypted header from the message
18
+ # @attr body [String] The encrypted body of the message
19
+ Payload = Struct.new(:header, :body)
20
+
21
+ ##
22
+ # Create a new instance of Decryptor
23
+ #
24
+ # @param public_key [String] The RSA public key used for decrypting the message. (Must be in pem format)
25
+ # @param payload [String] The message payload
26
+ def initialize(public_key, payload)
27
+ @key = OpenSSL::PKey::RSA.new(public_key)
28
+ @raw_payload = payload
29
+ end
30
+
31
+ ##
32
+ # Perform the decryption
33
+ #
34
+ # @return [String]
35
+ def call
36
+ payload = create_payload
37
+ header = decrypt_raw_header(payload.header)
38
+ case header.version
39
+ when 1
40
+ Sekret::BodyEncryption.decrypt(header, payload.body)
41
+ else
42
+ raise Sekret::Errors::UnsupportedVersionError, "Can't decrypt body with version: #{header.version}"
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def create_payload
49
+ parts = @raw_payload.split('.')
50
+ if parts.count != 2
51
+ raise Sekret::Errors::InvalidPayloadError, "Expected a header and a body. Found #{parts.count} parts."
52
+ end
53
+ Payload.new(
54
+ Sekret::Encoder.decode(parts[0]),
55
+ Sekret::Encoder.decode(parts[1])
56
+ )
57
+ end
58
+
59
+ def decrypt_raw_header(raw)
60
+ raw_header = @key.public_decrypt(raw)
61
+ Sekret::Header.from_decrypted(JSON.parse(raw_header))
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,36 @@
1
+ require 'base64'
2
+
3
+ module Sekret
4
+ ##
5
+ # Encode data objects into URL safe base64
6
+ #
7
+ # @author Maddie Schipper
8
+ # @since 1.0.0
9
+ #
10
+ # @private
11
+ class Encoder
12
+ class << self
13
+ ##
14
+ # Encode the value into URL safe base64
15
+ #
16
+ # @param value [String] the data to encode
17
+ #
18
+ # @return [String] A URL safe base64 encoded string
19
+ def encode(value)
20
+ Base64.urlsafe_encode64(value)
21
+ end
22
+
23
+ ##
24
+ # Decode the URL safe base64 string into it's raw data
25
+ #
26
+ # @param value [String] URL safe base64 string
27
+ #
28
+ # @return [String] A decoded data string
29
+ def decode(value)
30
+ ##
31
+ # Decode the URL safe base64 into it's raw format
32
+ Base64.urlsafe_decode64(value)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,57 @@
1
+ require_relative 'body_encryption'
2
+ require_relative 'encoder'
3
+ require_relative 'header'
4
+
5
+ module Sekret
6
+ ##
7
+ # Encrypt a message
8
+ #
9
+ # @author Maddie Schipper
10
+ # @since 1.0.0
11
+ class Encryptor
12
+ ##
13
+ # The version of the encryption format
14
+ VERSON = 1
15
+
16
+ ##
17
+ # Create a new instance of Encryptor
18
+ #
19
+ # @param private_key [String] The RSA private key used for encrypting the message. (Must be in pem format)
20
+ # @param payload [String] The message payload
21
+ #
22
+ # @return [Encryptor]
23
+ def initialize(private_key, payload)
24
+ @key = OpenSSL::PKey::RSA.new(private_key)
25
+ @payload = payload
26
+ end
27
+
28
+ ##
29
+ # Perform the encryption
30
+ #
31
+ # @return [String]
32
+ def call
33
+ result = Sekret::BodyEncryption.encrypt(@payload)
34
+ header = create_header(result)
35
+ [
36
+ Sekret::Encoder.encode(encrypt_header(header)),
37
+ Sekret::Encoder.encode(result.body)
38
+ ].join('.')
39
+ end
40
+
41
+ private
42
+
43
+ def create_header(result)
44
+ Sekret::Header.new(
45
+ result.checksum,
46
+ result.key,
47
+ result.iv,
48
+ VERSON,
49
+ Sekret::BodyEncryption::ALGORITHM
50
+ )
51
+ end
52
+
53
+ def encrypt_header(header)
54
+ @key.private_encrypt(header.to_s)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,40 @@
1
+ module Sekret
2
+ ##
3
+ # Custom errors raised by Sekret
4
+ module Errors
5
+ ##
6
+ # The base Error
7
+ #
8
+ # @author Maddie Schipper
9
+ # @since 1.0.0
10
+ class BaseError < StandardError; end
11
+
12
+ ##
13
+ # Error raised when a `mac_secret` isn't available for creating the message authenticity
14
+ #
15
+ # @author Maddie Schipper
16
+ # @since 1.0.0
17
+ class MissingMacSecretError < BaseError; end
18
+
19
+ ##
20
+ # Error raised if the encryption checksum doesn't match
21
+ #
22
+ # @author Maddie Schipper
23
+ # @since 1.0.0
24
+ class MissmatchedMacError < BaseError; end
25
+
26
+ ##
27
+ # Error raised if the payload to be decrypted is invalid
28
+ #
29
+ # @author Maddie Schipper
30
+ # @since 1.0.0
31
+ class InvalidPayloadError < BaseError; end
32
+
33
+ ##
34
+ # Error raised if the message header has an unsupported version
35
+ #
36
+ # @author Maddie Schipper
37
+ # @since 1.0.0
38
+ class UnsupportedVersionError < BaseError; end
39
+ end
40
+ end
@@ -0,0 +1,95 @@
1
+ require 'json'
2
+
3
+ require_relative 'encoder'
4
+
5
+ module Sekret
6
+ ##
7
+ # A Payload header
8
+ #
9
+ # @note You should never directly create a Header
10
+ #
11
+ # @author Maddie Schipper
12
+ # @since 1.0.0
13
+ #
14
+ # @private
15
+ class Header
16
+ ##
17
+ # The authenticity token for the header
18
+ # @return [String]
19
+ attr_reader :authenticity
20
+
21
+ ##
22
+ # The key used to encrypt the body
23
+ # @return [String]
24
+ attr_reader :key
25
+
26
+ ##
27
+ # The initialization vector used to encrypt the body
28
+ # @return [String]
29
+ attr_reader :iv
30
+
31
+ ##
32
+ # The encryption version for the body
33
+ # @return [Integer]
34
+ attr_reader :version
35
+
36
+ ##
37
+ # The encryption algorithm used to encrypt the body
38
+ # @return [String]
39
+ attr_reader :algorithm
40
+
41
+ ##
42
+ # Create a new header
43
+ #
44
+ # @note You should never directly create a Payload
45
+ #
46
+ # @param authenticity (see #authenticity)
47
+ # @param key (see #key)
48
+ # @param eiv (see #iv)
49
+ # @param version (see #version)
50
+ # @param algorithm (see #algorithm)
51
+ def initialize(authenticity, key, eiv, version, algorithm)
52
+ @authenticity = authenticity
53
+ @key = key
54
+ @iv = eiv
55
+ @version = version
56
+ @algorithm = algorithm
57
+ end
58
+
59
+ ##
60
+ # @private
61
+ #
62
+ # Create a header from a decrypted hash
63
+ def self.from_decrypted(hash)
64
+ new(
65
+ hash['aut'],
66
+ Encoder.decode(hash['key']),
67
+ Encoder.decode(hash['eiv']),
68
+ hash['ver'],
69
+ hash['alg']
70
+ )
71
+ end
72
+
73
+ ##
74
+ # Convert the header into it's hash format
75
+ #
76
+ # @return [Hash]
77
+ def to_h
78
+ {
79
+ aut: authenticity,
80
+ key: Encoder.encode(key),
81
+ eiv: Encoder.encode(iv),
82
+ ver: version,
83
+ alg: algorithm
84
+ }
85
+ end
86
+
87
+ ##
88
+ # Convert the header into it's string format
89
+ #
90
+ # @return [String]
91
+ def to_s
92
+ JSON.dump(to_h)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,36 @@
1
+ require 'openssl'
2
+
3
+ module Sekret
4
+ ##
5
+ # Create new keys for encryption
6
+ #
7
+ # @author Maddie Schipper
8
+ # @since 1.0.0
9
+ class KeyGenerator
10
+ ##
11
+ # A new key object
12
+ #
13
+ # @attr public_key [String] Public key in pem format.
14
+ # @attr private_key [String] Private key in pem format.
15
+ Key = Struct.new(:public_key, :private_key)
16
+
17
+ class << self
18
+ ##
19
+ # Generate a new RSA public/private key pair
20
+ #
21
+ # @param size [Integer] size of the RSA key to generate
22
+ # (defaults to 2048)
23
+ #
24
+ # @return [Key] the new public & private keys.
25
+ #
26
+ # @note The returned key is read-only
27
+ def generate_rsa_keys(size = 2048)
28
+ rsa_key = OpenSSL::PKey::RSA.new(size)
29
+ Key.new(
30
+ rsa_key.public_key.to_pem,
31
+ rsa_key.to_pem
32
+ ).freeze
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,5 @@
1
+ module Sekret
2
+ ##
3
+ # The current version of Sekret
4
+ VERSION = '1.0.0'.freeze
5
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sekret
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Maddie Schipper
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-10-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.10.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.10.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.16.1
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.16.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.9.16
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.9.16
97
+ description: Create/Decode semetric encryption
98
+ email:
99
+ - me@maddiesch.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - README.md
105
+ - Rakefile
106
+ - lib/sekret.rb
107
+ - lib/sekret/body_encryption.rb
108
+ - lib/sekret/checksum.rb
109
+ - lib/sekret/cli.rb
110
+ - lib/sekret/cli/help.txt.erb
111
+ - lib/sekret/cli/runner.rb
112
+ - lib/sekret/configuration.rb
113
+ - lib/sekret/decryptor.rb
114
+ - lib/sekret/encoder.rb
115
+ - lib/sekret/encryptor.rb
116
+ - lib/sekret/errors.rb
117
+ - lib/sekret/header.rb
118
+ - lib/sekret/key_generator.rb
119
+ - lib/sekret/version.rb
120
+ homepage: https://github.com/maddiesch/sekret
121
+ licenses: []
122
+ metadata:
123
+ allowed_push_host: https://rubygems.org
124
+ yard.run: yri
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 2.7.6
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: Semetric Encryption
145
+ test_files: []