aion-enigma 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +27 -0
  3. data/lib/aion-enigma.rb +1 -0
  4. data/lib/enigma.rb +110 -0
  5. metadata +78 -0
@@ -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
@@ -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
+ ```
@@ -0,0 +1 @@
1
+ require 'enigma'
@@ -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: []