jwe 0.2.0 → 0.3.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/README.md +3 -3
- data/lib/jwe/alg.rb +1 -0
- data/lib/jwe/alg/a128_kw.rb +13 -0
- data/lib/jwe/alg/a192_kw.rb +13 -0
- data/lib/jwe/alg/a256_kw.rb +13 -0
- data/lib/jwe/alg/aes_kw.rb +84 -0
- data/lib/jwe/version.rb +1 -1
- data/lib/jwe/zip/def.rb +9 -1
- data/spec/jwe/alg_spec.rb +34 -0
- data/spec/jwe/zip_spec.rb +6 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05c87a9be4e5864d4f31495bd609ff3d4abf1a68
|
4
|
+
data.tar.gz: dc5edbbac44a91be23673da3f5d0b2beb91a8245
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a26d929b4124949bbac9137855a32b42a9ab9165c0025e405e924937e99c9222e88096a1d5e40c93360f4e491df4f43ebe80a4f6d9fe0bba8bc34b9d10a94d99
|
7
|
+
data.tar.gz: b3e9575add99b0ad449c083a3981d419aaeaf17748591f00e293fcb61e556257b2b371af2c13c7ce8f294cfe72ec39d0f5cac7d6f2b46dd2c2864045410962dc
|
data/README.md
CHANGED
data/lib/jwe/alg.rb
CHANGED
@@ -0,0 +1,84 @@
|
|
1
|
+
module JWE
|
2
|
+
module Alg
|
3
|
+
module AesKw
|
4
|
+
attr_accessor :key
|
5
|
+
attr_accessor :iv
|
6
|
+
|
7
|
+
def initialize(key = nil, iv = "\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6")
|
8
|
+
self.iv = iv.force_encoding('ASCII-8BIT')
|
9
|
+
self.key = key.force_encoding('ASCII-8BIT')
|
10
|
+
end
|
11
|
+
|
12
|
+
def encrypt(cek)
|
13
|
+
a = iv
|
14
|
+
r = cek.scan(/.{8}/m)
|
15
|
+
|
16
|
+
6.times do |j|
|
17
|
+
r.length.times do |i|
|
18
|
+
b = encrypt_round(a + r[i])
|
19
|
+
|
20
|
+
a = b.chars.first(8).join
|
21
|
+
r[i] = b.chars.last(8).join
|
22
|
+
|
23
|
+
t = (r.length * j) + i + 1
|
24
|
+
a = xor(a, t)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
([a] + r).join
|
29
|
+
end
|
30
|
+
|
31
|
+
def decrypt(encrypted_cek)
|
32
|
+
c = encrypted_cek.scan(/.{8}/m)
|
33
|
+
a = c[0]
|
34
|
+
|
35
|
+
r = c[1..c.length]
|
36
|
+
|
37
|
+
5.downto(0) do |j|
|
38
|
+
r.length.downto(1) do |i|
|
39
|
+
t = (r.length * j) + i
|
40
|
+
a = xor(a, t)
|
41
|
+
|
42
|
+
b = decrypt_round(a + r[i - 1])
|
43
|
+
|
44
|
+
a = b.chars.first(8).join
|
45
|
+
r[i - 1] = b.chars.last(8).join
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
if a != iv
|
50
|
+
raise StandardError.new('The encrypted key has been tampered. Do not use this key.')
|
51
|
+
end
|
52
|
+
|
53
|
+
r.join
|
54
|
+
end
|
55
|
+
|
56
|
+
def cipher
|
57
|
+
@cipher ||= OpenSSL::Cipher.new(cipher_name)
|
58
|
+
rescue RuntimeError
|
59
|
+
raise JWE::NotImplementedError.new("The version of OpenSSL linked to your Ruby does not support the cipher #{cipher_name}.")
|
60
|
+
end
|
61
|
+
|
62
|
+
def encrypt_round(data)
|
63
|
+
cipher.encrypt
|
64
|
+
cipher.key = key
|
65
|
+
cipher.padding = 0
|
66
|
+
cipher.update(data) + cipher.final
|
67
|
+
end
|
68
|
+
|
69
|
+
def decrypt_round(data)
|
70
|
+
cipher.decrypt
|
71
|
+
cipher.key = key
|
72
|
+
cipher.padding = 0
|
73
|
+
cipher.update(data) + cipher.final
|
74
|
+
end
|
75
|
+
|
76
|
+
def xor(data, t)
|
77
|
+
t = ([0] * (data.length - 1)) + [t]
|
78
|
+
data = data.chars.map(&:ord)
|
79
|
+
|
80
|
+
data.zip(t).map { |a, b| (a ^ b).chr }.join
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/jwe/version.rb
CHANGED
data/lib/jwe/zip/def.rb
CHANGED
@@ -4,11 +4,19 @@ module JWE
|
|
4
4
|
module Zip
|
5
5
|
class Def
|
6
6
|
def compress(payload)
|
7
|
-
Zlib::Deflate.
|
7
|
+
zlib = Zlib::Deflate.new(Zlib::DEFAULT_COMPRESSION, -Zlib::MAX_WBITS)
|
8
|
+
zlib.deflate(payload)
|
9
|
+
zlib.finish
|
8
10
|
end
|
9
11
|
|
12
|
+
# Was using RFC 1950 instead of 1951.
|
10
13
|
def decompress(payload)
|
11
14
|
Zlib::Inflate.inflate(payload)
|
15
|
+
|
16
|
+
# Keeping compatibility for old encoded tokens
|
17
|
+
rescue Zlib::DataError
|
18
|
+
inflate = Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
19
|
+
inflate.inflate(payload)
|
12
20
|
end
|
13
21
|
end
|
14
22
|
end
|
data/spec/jwe/alg_spec.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require 'jwe/alg/dir'
|
2
2
|
require 'jwe/alg/rsa_oaep'
|
3
3
|
require 'jwe/alg/rsa15'
|
4
|
+
require 'jwe/alg/a128_kw'
|
5
|
+
require 'jwe/alg/a192_kw'
|
6
|
+
require 'jwe/alg/a256_kw'
|
4
7
|
require 'openssl'
|
5
8
|
|
6
9
|
describe JWE::Alg do
|
@@ -64,3 +67,34 @@ describe JWE::Alg::Rsa15 do
|
|
64
67
|
expect(alg.decrypt(ciphertext)).to eq 'random key'
|
65
68
|
end
|
66
69
|
end
|
70
|
+
|
71
|
+
[
|
72
|
+
JWE::Alg::A128Kw,
|
73
|
+
JWE::Alg::A192Kw,
|
74
|
+
JWE::Alg::A256Kw
|
75
|
+
].each_with_index do |klass, i|
|
76
|
+
describe klass do
|
77
|
+
let(:kek) { SecureRandom.random_bytes(16 + i * 8) }
|
78
|
+
let(:cek) { SecureRandom.random_bytes(32) }
|
79
|
+
let(:alg) { klass.new(kek) }
|
80
|
+
|
81
|
+
describe '#encrypt' do
|
82
|
+
it 'returns an encrypted string' do
|
83
|
+
expect(alg.encrypt(cek)).to_not eq cek
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'decrypts the encrypted key to the original key' do
|
88
|
+
ciphertext = alg.encrypt(cek)
|
89
|
+
expect(alg.decrypt(ciphertext)).to eq cek
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'raises when trying to decrypt tampered keys' do
|
93
|
+
alg = klass.new(kek, "\xA7\xA7\xA7\xA7\xA6\xA6\xA6\xA6")
|
94
|
+
ciphertext = alg.encrypt(cek)
|
95
|
+
|
96
|
+
bad_alg = klass.new(kek, "\xA7\xA7\xA7\xA7\xA7\xA7\xA7\xA7")
|
97
|
+
expect { bad_alg.decrypt(ciphertext) }.to raise_error(StandardError)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/spec/jwe/zip_spec.rb
CHANGED
@@ -18,4 +18,10 @@ describe JWE::Zip::Def do
|
|
18
18
|
deflated = deflate.compress('hello world')
|
19
19
|
expect(deflate.decompress(deflated)).to eq 'hello world'
|
20
20
|
end
|
21
|
+
|
22
|
+
it 'can deflate an RFC 1950 compressed message' do
|
23
|
+
deflated = Zlib::Deflate.deflate('hello world')
|
24
|
+
deflate = JWE::Zip::Def.new
|
25
|
+
expect(deflate.decompress(deflated)).to eq 'hello world'
|
26
|
+
end
|
21
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jwe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Francesco Boffa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-05-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -70,6 +70,10 @@ files:
|
|
70
70
|
- jwe.gemspec
|
71
71
|
- lib/jwe.rb
|
72
72
|
- lib/jwe/alg.rb
|
73
|
+
- lib/jwe/alg/a128_kw.rb
|
74
|
+
- lib/jwe/alg/a192_kw.rb
|
75
|
+
- lib/jwe/alg/a256_kw.rb
|
76
|
+
- lib/jwe/alg/aes_kw.rb
|
73
77
|
- lib/jwe/alg/dir.rb
|
74
78
|
- lib/jwe/alg/rsa15.rb
|
75
79
|
- lib/jwe/alg/rsa_oaep.rb
|