aion-enigma 0.0.1
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 +7 -0
- data/README.md +27 -0
- data/lib/aion-enigma.rb +1 -0
- data/lib/enigma.rb +110 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 123f2307cf57a446b1c46823bd3507bd83ce4784
|
4
|
+
data.tar.gz: 9cac96a9c1fd6ab3c6a591dd303f450ceb5a055c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 634e1f259feed493be4703935b9409461e6bc1dbb52c201551b09dcc81ca5484a73ee1d5c01020313b7fb45a8673e3d1f52e3c44af5bd9d8ee59cbcbe32050b8
|
7
|
+
data.tar.gz: 9fdcc2e6e9951444e2d4293fbef8180f1f8233fe4bfbf3f91cabbf862a53aac89faa85c5b3fb9b8d818f8942376eb6a7e6f0a3c0ca5317e8874bfa8118ba04bc
|
data/README.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Enigma
|
2
|
+
======
|
3
|
+
|
4
|
+
Enigma is a small utility for encrypting/decrypting a string based on a shared secret using AES-265-CBC.
|
5
|
+
|
6
|
+
Install
|
7
|
+
-------
|
8
|
+
|
9
|
+
Install gem via git
|
10
|
+
```
|
11
|
+
gem 'aion-enigma'
|
12
|
+
```
|
13
|
+
|
14
|
+
Usage
|
15
|
+
-----
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
secret_message = 'this is a secret message'
|
19
|
+
shared_secret = 'some shared secret'
|
20
|
+
|
21
|
+
enigma = Enigma.new(shared_secret)
|
22
|
+
encrypted_message = enigma.encrypt(secret_message)
|
23
|
+
# encrypted_message ≈> 'Gn3AZKG9aqv+ALTfI9ZbuQ==|7hI5iN1Jdm73zQB1nTBngX07SaX60nuirWQRtNygIgE='
|
24
|
+
|
25
|
+
message = enigma.decrypt(encrypted_message)
|
26
|
+
# message => 'this is a secret message'
|
27
|
+
```
|
data/lib/aion-enigma.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'enigma'
|
data/lib/enigma.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
class Enigma
|
5
|
+
|
6
|
+
class EncryptError < StandardError; end
|
7
|
+
class DecryptError < StandardError; end
|
8
|
+
|
9
|
+
# Creates an instance of Enigma using given shared secret
|
10
|
+
# @raise ArgumentError if secret is not a string
|
11
|
+
def initialize(secret)
|
12
|
+
unless secret.is_a? String
|
13
|
+
fail ArgumentError, 'secret must be a string'
|
14
|
+
end
|
15
|
+
@key = Digest::SHA1.hexdigest(secret)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Encrypts a string.
|
19
|
+
#
|
20
|
+
# @param message a string to encrypt
|
21
|
+
# @return a String
|
22
|
+
# @raise ArgumentError if message is not a string
|
23
|
+
# @raise EncryptError if encryption failed
|
24
|
+
def encrypt(message)
|
25
|
+
unless message.is_a? String
|
26
|
+
fail ArgumentError, 'message must be a string'
|
27
|
+
end
|
28
|
+
|
29
|
+
begin
|
30
|
+
cipher = OpenSSL::Cipher.new('aes-256-cbc')
|
31
|
+
|
32
|
+
cipher.encrypt
|
33
|
+
cipher.key = @key
|
34
|
+
|
35
|
+
cipher.iv = iv = cipher.random_iv
|
36
|
+
|
37
|
+
encrypted = cipher.update(message)
|
38
|
+
encrypted << cipher.final
|
39
|
+
|
40
|
+
pack(iv, encrypted)
|
41
|
+
rescue => _
|
42
|
+
fail EncryptError, 'Could not encode message.'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Decrypts an encrypted messages.
|
47
|
+
# If the secret does not match the encrypted message then
|
48
|
+
# an Enigma::DecryptError is raised.
|
49
|
+
#
|
50
|
+
# @param encrypted_message a string to decrypt (outputted by Enigma#encrypt)
|
51
|
+
# @return a String with the decrypted message
|
52
|
+
# @raise ArgumentError if encrypted_message is not a string
|
53
|
+
# @raise DecryptError if Decryption failed
|
54
|
+
|
55
|
+
def decrypt(encrypted_message)
|
56
|
+
unless encrypted_message.is_a? String
|
57
|
+
fail ArgumentError, 'encrypted_message must be a string'
|
58
|
+
end
|
59
|
+
|
60
|
+
begin
|
61
|
+
iv, encrypted_message = unpack(encrypted_message)
|
62
|
+
|
63
|
+
cipher = OpenSSL::Cipher.new('aes-256-cbc')
|
64
|
+
cipher.decrypt
|
65
|
+
cipher.key = @key
|
66
|
+
|
67
|
+
cipher.iv = iv
|
68
|
+
|
69
|
+
decrypted = cipher.update(encrypted_message)
|
70
|
+
decrypted << cipher.final
|
71
|
+
|
72
|
+
decrypted
|
73
|
+
rescue => _
|
74
|
+
fail DecryptError, 'Could not decode encrypted message.'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
protected
|
79
|
+
|
80
|
+
# Packing the encrypted message into a string.
|
81
|
+
#
|
82
|
+
# Enigma#pack and Enigma#unpack can be overridden from a subclass.
|
83
|
+
# Just make sure that the following still holds:
|
84
|
+
#
|
85
|
+
# iv2, encrypted2 = unpack(pack(iv1, encrypted1)
|
86
|
+
# iv1 == iv2 and encrypted1 == encrypted2
|
87
|
+
#
|
88
|
+
# @param iv the random iv (bytes) generated by the cipher
|
89
|
+
# @param encrypted the encrypted bytes
|
90
|
+
# @return String with serialized iv and encrypted parameters
|
91
|
+
def pack(iv, encrypted)
|
92
|
+
[iv, encrypted].map { |x| Base64.encode64(x).strip }.join('|')
|
93
|
+
end
|
94
|
+
|
95
|
+
# Unpacking the encrypted_message into an array of iv and encrypted data.
|
96
|
+
#
|
97
|
+
# Enigma#pack and Enigma#unpack can be overridden from a subclass.
|
98
|
+
# Just make sure that the following still holds:
|
99
|
+
#
|
100
|
+
# iv2, encrypted2 = unpack(pack(iv1, encrypted1)
|
101
|
+
# iv1 == iv2 and encrypted1 == encrypted2
|
102
|
+
#
|
103
|
+
# @param encrypted_message as outputted by Enigma#pack
|
104
|
+
# @return Array containing iv bytes and encrypted bytes
|
105
|
+
def unpack(encrypted_message)
|
106
|
+
encrypted_message.split('|').map { |m| Base64.decode64(m) }
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aion-enigma
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Andersen
|
8
|
+
- Eugene Zainchkovskyy
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-09-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '11.2'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '11.2'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: minitest
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '5.9'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '5.9'
|
42
|
+
description: Small utility for encrypting/decrypting a string based on a shared secret.
|
43
|
+
Based on AES-265-CBC.
|
44
|
+
email:
|
45
|
+
- michael@aion.dk
|
46
|
+
- eugene@3bytesahead.com
|
47
|
+
executables: []
|
48
|
+
extensions: []
|
49
|
+
extra_rdoc_files: []
|
50
|
+
files:
|
51
|
+
- README.md
|
52
|
+
- lib/aion-enigma.rb
|
53
|
+
- lib/enigma.rb
|
54
|
+
homepage: https://github.com/aion-dk/enigma
|
55
|
+
licenses:
|
56
|
+
- MIT
|
57
|
+
metadata: {}
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 2.4.5.1
|
75
|
+
signing_key:
|
76
|
+
specification_version: 4
|
77
|
+
summary: Encryption utility based on AES
|
78
|
+
test_files: []
|