rijndael 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ab1bbc3284ccfa1fc6aa42c955e9ac7a07a87006
4
+ data.tar.gz: d6c2d3614e14c6532f75d513a012807ccd7e0f5d
5
+ SHA512:
6
+ metadata.gz: 91a5efc5b365d9f1fbb3c3371e5622e3931f2b9cce4e476a50d32992fcc32b7d94512d9748c34f68b20c1db99cbd40939e551fe33c3e8f04ef6f75fd18ddbe79
7
+ data.tar.gz: f56b57521bc05b136e063a829d64653d33d9c3b5d3650c5d0bf1fe8d70d5d003e6f82854e7973d0a00793c4fac841c0cc9f91a74f0c9dab91d12448b9965d017
data/bin/rijndael ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rijndael'
4
+ require 'yaml'
5
+ require 'optparse'
6
+
7
+ options = {
8
+ crypt: []
9
+ }
10
+
11
+ parser = OptionParser.new do |opts|
12
+ opts.banner = <<HELP
13
+ Usage:
14
+ rijndael -k
15
+ rijndael (-e 'plain' | -d 'cipher')...
16
+ rijndael -k key [-e 'plain' | -d 'cipher']...
17
+ HELP
18
+ opts.separator 'Options:'
19
+ opts.on('-k', '--key [KEY]', 'Generate or use key') do |key|
20
+ options[:key] = key
21
+ end
22
+ opts.on('-e', '--encrypt PLAIN', 'Encrypt plain text') do |plain|
23
+ options[:crypt] << { action: :encrypt, value: plain }
24
+ end
25
+ opts.on('-d', '--decrypt CIPHER', 'Decrypt cipher text') do |cipher|
26
+ options[:crypt] << { action: :decrypt, value: cipher }
27
+ end
28
+ opts.on_tail('-h', '--help', 'Print this help') do
29
+ puts opts
30
+ exit
31
+ end
32
+ end
33
+ parser.parse!
34
+
35
+ if !options.key?(:key) && options[:crypt].empty?
36
+ puts parser
37
+ exit
38
+ end
39
+
40
+ if options[:key].nil?
41
+ options[:key] = Rijndael::Base.generate_key
42
+ puts "Generated key: #{options[:key]}"
43
+ end
44
+
45
+ rijndael = Rijndael::Base.new(options[:key])
46
+
47
+ options[:crypt].each do |crypt|
48
+ puts rijndael.send(crypt[:action], crypt[:value])
49
+ end
data/lib/rijndael.rb ADDED
@@ -0,0 +1 @@
1
+ require 'rijndael/base'
@@ -0,0 +1,85 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+ require 'yaml'
4
+ require 'rijndael/deep_decrypt'
5
+
6
+ #:nodoc:
7
+ module Rijndael
8
+ CIPHER_PATTERN = %r(^\$([a-zA-Z0-9+/]+={0,2})\$([a-zA-Z0-9+/]+={0,2})$)
9
+
10
+ ##
11
+ # Simply encrypt and decrypt strings using Rijndael.
12
+ #
13
+ class Base
14
+ include DeepDecrypt
15
+
16
+ ##
17
+ # This constructor sets the de-/encryption key.
18
+ #
19
+ # @param key [String] Encryption key.
20
+ #
21
+ def initialize(key)
22
+ @key = key
23
+ fail ArgumentError, 'Key is empty.' if key.nil? || key.empty?
24
+ end
25
+
26
+ ##
27
+ # This method expects a plain text of arbitrary length and encrypts it.
28
+ #
29
+ # @param plain [String] Plain text.
30
+ #
31
+ # @return [String] Cipher text.
32
+ #
33
+ def encrypt(plain)
34
+ fail ArgumentError, 'No plain text supplied.' if plain.nil? || plain.empty?
35
+
36
+ cipher = self.class.cipher
37
+ cipher.encrypt
38
+ cipher.key = Base64.decode64(@key)
39
+ cipher.iv = iv = cipher.random_iv
40
+ encrypted = cipher.update(plain)
41
+ encrypted << cipher.final
42
+
43
+ iv = Base64.strict_encode64(iv)
44
+ encrypted = Base64.strict_encode64(encrypted)
45
+
46
+ "$#{iv}$#{encrypted}"
47
+ end
48
+
49
+ ##
50
+ # This method expects a base64 encoded cipher text and decrypts it.
51
+ #
52
+ # @param encrypted [String] Cipher text.
53
+ #
54
+ # @return [String] Plain text.
55
+ #
56
+ def decrypt(encrypted)
57
+ fail ArgumentError, 'No cipher text supplied.' if encrypted.nil? || encrypted.empty?
58
+
59
+ matches = CIPHER_PATTERN.match(encrypted)
60
+
61
+ fail ArgumentError, 'Cipher text has an unsupported format.' if matches.nil?
62
+
63
+ cipher = self.class.cipher
64
+ cipher.decrypt
65
+ cipher.key = Base64.decode64(@key)
66
+ cipher.iv = Base64.decode64(matches[1])
67
+ decrypted = cipher.update(Base64.decode64(matches[2]))
68
+
69
+ decrypted << cipher.final
70
+ end
71
+
72
+ ##
73
+ # Generate a random key for encryption.
74
+ #
75
+ # @return [String] Encryption key.
76
+ #
77
+ def self.generate_key
78
+ Base64.strict_encode64(cipher.random_key)
79
+ end
80
+
81
+ def self.cipher
82
+ @cipher ||= OpenSSL::Cipher.new 'aes-256-cbc'
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,48 @@
1
+ ##
2
+ # Include DeepDecrypter and implement decrypt(String) to make use of:
3
+ # - decrypt_str
4
+ # - decrypt_each
5
+ # - decrypt_hash
6
+ # - decrypt_deep
7
+ #
8
+ module DeepDecrypt
9
+ def decrypt_deep(obj)
10
+ case obj
11
+ when String
12
+ decrypt_str(obj)
13
+ when Array
14
+ decrypt_each(obj)
15
+ when Hash
16
+ decrypt_hash(obj)
17
+ else
18
+ obj
19
+ end
20
+ end
21
+
22
+ def decrypt_str(str)
23
+ str = str.dup
24
+ if str =~ Rijndael::CIPHER_PATTERN
25
+ decrypt(str)
26
+ else
27
+ str
28
+ end
29
+ end
30
+
31
+ def decrypt_each(arr)
32
+ res = arr.class.new
33
+ arr.each do |v|
34
+ res << decrypt_deep(v)
35
+ end
36
+
37
+ res
38
+ end
39
+
40
+ def decrypt_hash(hash)
41
+ res = hash.class.new
42
+ hash.each do |k, v|
43
+ res[k] = decrypt_deep(v)
44
+ end
45
+
46
+ res
47
+ end
48
+ end
@@ -0,0 +1,4 @@
1
+ #:nodoc:
2
+ module Rijndael
3
+ VERSION = '0.0.1'
4
+ end
@@ -0,0 +1,3 @@
1
+ require 'pp'
2
+ require 'minitest/autorun'
3
+ require 'rijndael'
@@ -0,0 +1,66 @@
1
+ require_relative 'test_helper'
2
+
3
+ # Test Crypt functionality
4
+ class TestCrypt < Minitest::Test
5
+ def setup
6
+ @crypt = Rijndael::Base.new('7xnfakb9k1xKWsoUWUtXhGR9qsG+tkdOXdvKGbRkXGY=')
7
+ end
8
+
9
+ def test_loading_empty_key_should_fail
10
+ ex = assert_raises ArgumentError do
11
+ Rijndael::Base.new(nil)
12
+ end
13
+ assert_equal 'Key is empty.', ex.message
14
+
15
+ ex = assert_raises ArgumentError do
16
+ Rijndael::Base.new('')
17
+ end
18
+ assert_equal 'Key is empty.', ex.message
19
+ end
20
+
21
+ def test_encryption
22
+ e = @crypt.encrypt('plain text')
23
+ assert_match Rijndael::CIPHER_PATTERN, e
24
+ end
25
+
26
+ def test_decryption
27
+ d = @crypt.decrypt('$lCNNFWadM6/QIfbdAWJP/g==$oCUTE1bRE2Z7jNM0bRNs4A==')
28
+ assert_equal 'plain text', d
29
+ end
30
+
31
+ def test_failing_enryption_should_raise
32
+ ex = assert_raises ArgumentError do
33
+ @crypt.decrypt('foobar')
34
+ end
35
+ assert_equal 'Cipher text has an unsupported format.', ex.message
36
+ end
37
+
38
+ def test_deep_decryption_str
39
+ d = @crypt.decrypt_deep('$lCNNFWadM6/QIfbdAWJP/g==$SCzLNbG700CIzFifl9yzeg==')
40
+ assert_equal 'deep text', d
41
+ end
42
+
43
+ def test_deep_decryption_array
44
+ d = @crypt.decrypt_deep(%w(plain $lCNNFWadM6/QIfbdAWJP/g==$SCzLNbG700CIzFifl9yzeg== text))
45
+ assert d.include?('deep text')
46
+ end
47
+
48
+ def test_deep_decryption_hash
49
+ d = @crypt.decrypt_deep(
50
+ key: 'value',
51
+ cipher: '$lCNNFWadM6/QIfbdAWJP/g==$SCzLNbG700CIzFifl9yzeg=='
52
+ )
53
+ assert_equal 'deep text', d[:cipher]
54
+ end
55
+
56
+ def test_deep_decryption_complex
57
+ d = @crypt.decrypt_deep(
58
+ key: 'value',
59
+ hash: {
60
+ array: %w(plain $lCNNFWadM6/QIfbdAWJP/g==$SCzLNbG700CIzFifl9yzeg== text),
61
+ time: Time.now
62
+ }
63
+ )
64
+ assert d[:hash][:array].include?('deep text')
65
+ end
66
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rijndael
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Finn Glöe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '10.4'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '10.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.6'
41
+ description: Easily encrypt and decrypt strings using AES. Rijndael is a wrapper around
42
+ OpenSSL::Cipher to abstract to a minimum of needed methods.
43
+ email: finn.gloee@1und1.de
44
+ executables:
45
+ - rijndael
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - bin/rijndael
50
+ - lib/rijndael.rb
51
+ - lib/rijndael/base.rb
52
+ - lib/rijndael/deep_decrypt.rb
53
+ - lib/rijndael/version.rb
54
+ - test/test_helper.rb
55
+ - test/test_rijndael.rb
56
+ homepage: https://github.com/1and1/rijndael
57
+ licenses:
58
+ - GPL v2
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 2.4.6
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: Easily encrypt and decrypt strings using AES.
80
+ test_files:
81
+ - test/test_helper.rb
82
+ - test/test_rijndael.rb