ece 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 44649fdca6ff58ef3b0831277607fa979a2c206c
4
+ data.tar.gz: 8197c1f1d10916433b2ef9a42fce6fa4b47c12df
5
+ SHA512:
6
+ metadata.gz: f6e325e8147ed9d6f60fef039ce81fb632b01499b9e662b8cb5d20612714d0fbef19ec89eee9563580ce01bb7d6a7ff9278d0f8ace6162a63f2818faf656b202
7
+ data.tar.gz: 4cde40d586d950843e4e853a7c3f8d5c8137bdad88e5faa751380a59aba5e74d7e2cc1a5cdda5de83ef9e2ca6c9d1c14fac6cc8db19420112d76e8aedb0900cc
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /*.gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ece.gemspec
4
+ gemspec
@@ -0,0 +1,40 @@
1
+ # Ece
2
+
3
+ Ruby implementation of encrypted content-encoding.
4
+
5
+ https://tools.ietf.org/html/draft-thomson-http-encryption-02
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'ece'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install ece
22
+
23
+ ## Usage
24
+
25
+ ```
26
+ require 'ece'
27
+
28
+ key = Random.new.bytes(16)
29
+ salt = Random.new.bytes(16)
30
+ data = "Your very private data"
31
+
32
+ Ece.encrypt(data, key: key, salt: salt)
33
+
34
+ Ece.decrypt(data, key: key, salt: salt)
35
+ ```
36
+ Data can be bytestring as well.
37
+ ## Contributing
38
+
39
+ Bug reports and pull requests are welcome on GitHub at https://github.com/randomlogin/ece.
40
+
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ece/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ece"
8
+ spec.version = Ece::VERSION
9
+ spec.authors = ["Alexander Shevtsov"]
10
+ spec.email = ["randomlogin76@gmail.com"]
11
+
12
+ spec.summary = "Ruby implementation of encrypted content-encoding"
13
+ spec.homepage = "https://github.com/randomlogin/ece"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.bindir = "exe"
17
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.11"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_dependency 'hkdf'
23
+ end
@@ -0,0 +1,3 @@
1
+ require 'ece/version'
2
+ require 'ece/ece'
3
+
@@ -0,0 +1,89 @@
1
+ require 'openssl'
2
+ require 'hkdf'
3
+ require 'base64'
4
+
5
+ #fore testing purposes only
6
+ #TODO: variable padding
7
+
8
+ class Ece
9
+
10
+ KEY_LENGTH=16
11
+ TAG_LENGTH=16
12
+ NONCE_LENGTH=12
13
+
14
+ def self.hmac_hash(key, input)
15
+ digest = OpenSSL::Digest.new('sha256')
16
+ OpenSSL::HMAC.digest(digest, key, input)
17
+ end
18
+
19
+ def self.hkdf_extract(salt, ikm)
20
+ hmac_hash(salt,ikm)
21
+ end
22
+
23
+ def self.extract_key(params)
24
+ raise "Salt must be 16-bytes long" unless params[:salt].length==16
25
+ key = HKDF.new(params[:key], salt: params[:salt], algorithm: 'sha256', info: "Content-Encoding: aesgcm128")
26
+ nonce = HKDF.new(params[:key], salt: params[:salt], algorithm: 'sha256', info: "Content-Encoding: nonce")
27
+ {key: key.next_bytes(KEY_LENGTH), nonce: nonce.next_bytes(NONCE_LENGTH)}
28
+ end
29
+
30
+ def self.generate_nonce(nonce, counter)
31
+ raise "Nonce must be #{NONCE_LENGTH} bytes long." unless nonce.length == NONCE_LENGTH
32
+ output = nonce.dup
33
+ integer = nonce[-6..-1].unpack('B*')[0].to_i(2) #taking last 6 bytes, treating as integer
34
+ x = ((integer ^ counter) & 0xffffff) + ((((integer / 0x1000000) ^ (counter / 0x1000000)) & 0xffffff) * 0x1000000)
35
+ output[-6..-1] = [x.to_s(16)].pack('H*')
36
+ output
37
+ end
38
+
39
+ def self.encrypt_record(params, counter, buffer, pad=0)
40
+ raise "Key must be #{KEY_LENGTH} bytes long" unless params[:key].length == KEY_LENGTH
41
+ gcm = OpenSSL::Cipher.new('aes-128-gcm')
42
+ gcm.encrypt
43
+ gcm.key = params[:key]
44
+ gcm.iv = generate_nonce(params[:nonce], counter)
45
+ enc = gcm.update("\x00"+buffer) + gcm.final + gcm.auth_tag #enc = gcm.update("\x00"*pad+buffer)+gcm.final + gcm.auth_tag padding is not fully implemented for now
46
+ enc
47
+ end
48
+
49
+ def self.encrypt(data, params)
50
+ key = extract_key(params)
51
+ rs = 4095 #look TODO
52
+ result = ""
53
+ counter = 0
54
+ (0..data.length).step(rs) do |i|
55
+ block = encrypt_record(key, counter, data[i..i+rs-1])
56
+ result += block
57
+ counter +=1
58
+ end
59
+ result
60
+ end
61
+
62
+ def self.decrypt_record(params, counter, buffer, pad=0)
63
+ raise "Key must be #{KEY_LENGTH} bytes long" unless params[:key].length == KEY_LENGTH
64
+ gcm = OpenSSL::Cipher.new('aes-128-gcm')
65
+ gcm.decrypt
66
+ gcm.key = params[:key]
67
+ gcm.iv = generate_nonce(params[:nonce], counter)
68
+ gcm.auth_tag = buffer[-16..-1]
69
+ decrypted = gcm.update(buffer[0..-17]) + gcm.final
70
+ #padding = decrypted[0]
71
+ #padding_length = decrypted[0].unpack("C")
72
+ #raise Err unless padding = "\x00"*padding_length
73
+ decrypted[1..-1]
74
+ end
75
+
76
+ def self.decrypt(data, params)
77
+ key = extract_key(params)
78
+ rs = 4096+16 #not changeable for now
79
+ result = ""
80
+ counter = 0
81
+ (0..data.length).step(rs) do |i|
82
+ block = decrypt_record(key, counter, data[i..i+rs-1])
83
+ result += block
84
+ counter +=1
85
+ end
86
+ result
87
+ end
88
+
89
+ end
@@ -0,0 +1,3 @@
1
+ class Ece
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ece
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Shevtsov
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-12-21 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.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: hkdf
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description:
56
+ email:
57
+ - randomlogin76@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - README.md
65
+ - Rakefile
66
+ - ece.gemspec
67
+ - lib/ece.rb
68
+ - lib/ece/ece.rb
69
+ - lib/ece/version.rb
70
+ homepage: https://github.com/randomlogin/ece
71
+ licenses: []
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 2.4.8
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Ruby implementation of encrypted content-encoding
93
+ test_files: []