ece 0.1.4 → 0.2.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.
- checksums.yaml +4 -4
- data/lib/ece/ece.rb +47 -10
- data/lib/ece/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c93241d913169ee1b99d4981b7984c677c4f43ed
|
4
|
+
data.tar.gz: d7b99ebadb19980c081b870c0dde6e83f7cc7259
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd8783c304738147ac82eb572de3f773cd5097303c4e03ff06cbc701b2368b7160722bc42fb1cb3f5ba0147ac07dabf9f4a01408230dfc14568ab9ea166b2034
|
7
|
+
data.tar.gz: d538fb755d02ac2965e2c8134694453b559d38bef5f4cd8961b2f78cc25a69bb5c5a93dfad01cd812d959de87fd0fde93871f8da3f846c73ec57b263a726ae42
|
data/lib/ece/ece.rb
CHANGED
@@ -9,6 +9,7 @@ class ECE
|
|
9
9
|
KEY_LENGTH=16
|
10
10
|
TAG_LENGTH=16
|
11
11
|
NONCE_LENGTH=12
|
12
|
+
SHA256_LENGTH=32
|
12
13
|
|
13
14
|
def self.hmac_hash(key, input)
|
14
15
|
digest = OpenSSL::Digest.new('sha256')
|
@@ -18,12 +19,30 @@ class ECE
|
|
18
19
|
def self.hkdf_extract(salt, ikm) #ikm stays for input keying material
|
19
20
|
hmac_hash(salt,ikm)
|
20
21
|
end
|
22
|
+
|
23
|
+
def self.get_info(type, client_public, server_public)
|
24
|
+
cl_len_no = [client_public.size].pack('n')
|
25
|
+
sv_len_no = [server_public.size].pack('n')
|
26
|
+
"Content-Encoding: #{type}\x00P-256\x00#{cl_len_no}#{client_public}#{sv_len_no}#{server_public}"
|
27
|
+
end
|
21
28
|
|
22
29
|
def self.extract_key(params)
|
23
30
|
raise "Salt must be 16-bytes long" unless params[:salt].length==16
|
24
|
-
|
25
|
-
|
26
|
-
|
31
|
+
|
32
|
+
input_key = params[:key]
|
33
|
+
auth = false
|
34
|
+
if params.has_key?(:auth) # Encrypted Content Encoding, March 11 2016, http://httpwg.org/http-extensions/draft-ietf-httpbis-encryption-encoding.html
|
35
|
+
auth = true
|
36
|
+
input = HKDF.new(input_key, {salt: params[:auth] , algorithm: 'sha256', info: "Content-Encoding: auth\x00"})
|
37
|
+
input_key = input.next_bytes(SHA256_LENGTH)
|
38
|
+
secret = HKDF.new(input_key, {salt: params[:salt], algorithm: 'sha256', info: get_info("aesgcm", params[:user_public_key], params[:server_public_key])})
|
39
|
+
nonce = HKDF.new(input_key, salt: params[:salt], algorithm: 'sha256', info: get_info("nonce", params[:user_public_key], params[:server_public_key]))
|
40
|
+
else
|
41
|
+
secret = HKDF.new(input_key, {salt: params[:salt], algorithm: 'sha256', info: "Content-Encoding: aesgcm128"})
|
42
|
+
nonce = HKDF.new(input_key, salt: params[:salt], algorithm: 'sha256', info: "Content-Encoding: nonce")
|
43
|
+
end
|
44
|
+
|
45
|
+
{key: secret.next_bytes(KEY_LENGTH), nonce: nonce.next_bytes(NONCE_LENGTH), auth: auth}
|
27
46
|
end
|
28
47
|
|
29
48
|
def self.generate_nonce(nonce, counter)
|
@@ -39,12 +58,13 @@ class ECE
|
|
39
58
|
def self.encrypt(data, params)
|
40
59
|
key = extract_key(params)
|
41
60
|
rs = params[:rs] ? params [:rs] : 4096
|
61
|
+
padsize = params[:padsize] ? params [:padsize] : 0
|
42
62
|
raise "The rs parameter must be greater than 1." if rs <= 1
|
43
63
|
rs -=1 #this ensures encrypted data cannot be truncated
|
44
64
|
result = ""
|
45
65
|
counter = 0
|
46
66
|
(0..data.length).step(rs) do |i|
|
47
|
-
block = encrypt_record(key, counter, data[i..i+rs-1])
|
67
|
+
block = encrypt_record(key, counter, data[i..i+rs-1], padsize)
|
48
68
|
result += block
|
49
69
|
counter +=1
|
50
70
|
end
|
@@ -75,11 +95,20 @@ class ECE
|
|
75
95
|
raise "Block is too small" if buffer.length <= TAG_LENGTH+1
|
76
96
|
gcm.auth_tag = buffer[-TAG_LENGTH..-1]
|
77
97
|
decrypted = gcm.update(buffer[0..-TAG_LENGTH-1]) + gcm.final
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
98
|
+
|
99
|
+
if params[:auth]
|
100
|
+
padding_length = decrypted[0..1].unpack("n")[0]
|
101
|
+
raise "Padding is too big" if padding_length+2 > decrypted.length
|
102
|
+
padding = decrypted[2..padding_length]
|
103
|
+
raise "Wrong padding" unless padding = "\x00"*padding_length
|
104
|
+
return decrypted[2+padding_length..-1]
|
105
|
+
else
|
106
|
+
padding_length = decrypted[0].unpack("C")[0]
|
107
|
+
raise "Padding is too big" if padding_length+1 > decrypted.length
|
108
|
+
padding = decrypted[1..padding_length]
|
109
|
+
raise "Wrong padding" unless padding = "\x00"*padding_length
|
110
|
+
return decrypted[1..-1]
|
111
|
+
end
|
83
112
|
end
|
84
113
|
|
85
114
|
def self.encrypt_record(params, counter, buffer, pad=0)
|
@@ -88,7 +117,15 @@ class ECE
|
|
88
117
|
gcm.key = params[:key]
|
89
118
|
gcm.iv = generate_nonce(params[:nonce], counter)
|
90
119
|
gcm.auth_data = ""
|
91
|
-
|
120
|
+
padding = ""
|
121
|
+
if params[:auth]
|
122
|
+
padding = [pad].pack('n') + "\x00"*pad # 2 bytes, big endian, then n zero bytes of padding
|
123
|
+
buf = padding+buffer
|
124
|
+
record = gcm.update(buf)
|
125
|
+
else
|
126
|
+
record = gcm.update("\x00"+buffer) # 1 padding byte, not fully implemented
|
127
|
+
end
|
128
|
+
enc = record + gcm.final + gcm.auth_tag
|
92
129
|
enc
|
93
130
|
end
|
94
131
|
|
data/lib/ece/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ece
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Shevtsov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|