sekret 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +30 -0
- data/Rakefile +19 -0
- data/lib/sekret.rb +30 -0
- data/lib/sekret/body_encryption.rb +87 -0
- data/lib/sekret/checksum.rb +25 -0
- data/lib/sekret/cli.rb +17 -0
- data/lib/sekret/cli/help.txt.erb +10 -0
- data/lib/sekret/cli/runner.rb +69 -0
- data/lib/sekret/configuration.rb +31 -0
- data/lib/sekret/decryptor.rb +64 -0
- data/lib/sekret/encoder.rb +36 -0
- data/lib/sekret/encryptor.rb +57 -0
- data/lib/sekret/errors.rb +40 -0
- data/lib/sekret/header.rb +95 -0
- data/lib/sekret/key_generator.rb +36 -0
- data/lib/sekret/version.rb +5 -0
- metadata +145 -0
checksums.yaml
ADDED
@@ -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
|
data/README.md
ADDED
@@ -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
|
+
```
|
data/Rakefile
ADDED
@@ -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
|
data/lib/sekret.rb
ADDED
@@ -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
|
data/lib/sekret/cli.rb
ADDED
@@ -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,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
|
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: []
|