jwe 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +2 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +1 -0
- data/README.md +134 -0
- data/Rakefile +1 -2
- data/jwe.gemspec +1 -1
- data/lib/jwe.rb +12 -12
- data/lib/jwe/alg.rb +1 -1
- data/lib/jwe/alg/dir.rb +2 -2
- data/lib/jwe/base64.rb +2 -2
- data/lib/jwe/enc.rb +1 -1
- data/lib/jwe/enc/aes_cbc_hs.rb +7 -7
- data/lib/jwe/enc/aes_gcm.rb +2 -2
- data/lib/jwe/serialization/compact.rb +1 -1
- data/lib/jwe/version.rb +1 -2
- data/lib/jwe/zip.rb +1 -1
- data/spec/jwe/base64_spec.rb +4 -4
- data/spec/jwe/enc_spec.rb +2 -2
- data/spec/jwe/serialization_spec.rb +2 -2
- data/spec/jwe/zip_spec.rb +2 -2
- data/spec/jwe_spec.rb +34 -4
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d669663ec6b48136c82b078fa3d01c0d6c03a92a
|
4
|
+
data.tar.gz: 62ede4a2f3ea9044e727a27a28642ce183864b99
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37054c453193a2e56d31d8269eeb29a3159646dbe073fd856abc4a3a567b843689e4cef436bb77e4c6e7b1059070399b1912725ebaa60bf4ccc6593179447d3f
|
7
|
+
data.tar.gz: e46636207448627d548d7804754b17d4d66962aef10b0d40193da75b0af2222c1d006971ab432e7e356c744b415cee2a12c3f29fea630f732d75c309e56a602f
|
data/.codeclimate.yml
CHANGED
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/README.md
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
# JWE
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/jwt/ruby-jwe.svg)](https://travis-ci.org/jwt/ruby-jwe)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/aomega08/jwe/badges/gpa.svg)](https://codeclimate.com/github/aomega08/jwe)
|
5
|
+
[![Test Coverage](https://codeclimate.com/github/aomega08/jwe/badges/coverage.svg)](https://codeclimate.com/github/aomega08/jwe/coverage)
|
6
|
+
|
7
|
+
A ruby implementation of the [RFC 7516 JSON Web Encryption (JWE)](https://tools.ietf.org/html/rfc7516) standard.
|
8
|
+
|
9
|
+
## Installing
|
10
|
+
|
11
|
+
```bash
|
12
|
+
gem install jwe
|
13
|
+
```
|
14
|
+
## Usage
|
15
|
+
|
16
|
+
This example uses the default alg and enc methods (RSA-OAEP and A128CBC-HS256). It requires an RSA key.
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
require 'jwe'
|
20
|
+
|
21
|
+
key = OpenSSL::PKey::RSA.generate(2048)
|
22
|
+
payload = "The quick brown fox jumps over the lazy dog."
|
23
|
+
|
24
|
+
encrypted = JWE.encrypt(payload, key)
|
25
|
+
puts encrypted
|
26
|
+
|
27
|
+
plaintext = JWE.decrypt(encrypted, key)
|
28
|
+
puts plaintext #"The quick brown fox jumps over the lazy dog."
|
29
|
+
```
|
30
|
+
|
31
|
+
This example uses a custom enc method:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
require 'jwe'
|
35
|
+
|
36
|
+
key = OpenSSL::PKey::RSA.generate(2048)
|
37
|
+
payload = "The quick brown fox jumps over the lazy dog."
|
38
|
+
|
39
|
+
encrypted = JWE.encrypt(payload, key, enc: 'A192GCM')
|
40
|
+
puts encrypted
|
41
|
+
|
42
|
+
plaintext = JWE.decrypt(encrypted, key)
|
43
|
+
puts plaintext #"The quick brown fox jumps over the lazy dog."
|
44
|
+
```
|
45
|
+
|
46
|
+
This example uses the 'dir' alg method. It requires an encryption key of the correct size for the enc method
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
require 'jwe'
|
50
|
+
|
51
|
+
key = SecureRandom.random_bytes(32)
|
52
|
+
payload = "The quick brown fox jumps over the lazy dog."
|
53
|
+
|
54
|
+
encrypted = JWE.encrypt(payload, key, alg: 'dir')
|
55
|
+
puts encrypted
|
56
|
+
|
57
|
+
plaintext = JWE.decrypt(encrypted, key)
|
58
|
+
puts plaintext #"The quick brown fox jumps over the lazy dog."
|
59
|
+
```
|
60
|
+
|
61
|
+
This example uses the DEFLATE algorithm on the plaintext to reduce the result size.
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
require 'jwe'
|
65
|
+
|
66
|
+
key = OpenSSL::PKey::RSA.generate(2048)
|
67
|
+
payload = "The quick brown fox jumps over the lazy dog."
|
68
|
+
|
69
|
+
encrypted = JWE.encrypt(payload, key, zip: 'DEF')
|
70
|
+
puts encrypted
|
71
|
+
|
72
|
+
plaintext = JWE.decrypt(encrypted, key)
|
73
|
+
puts plaintext #"The quick brown fox jumps over the lazy dog."
|
74
|
+
```
|
75
|
+
|
76
|
+
## Available Algorithms
|
77
|
+
|
78
|
+
The RFC 7518 JSON Web Algorithms (JWA) spec defines the algorithms for [encryption](https://tools.ietf.org/html/rfc7518#section-5.1)
|
79
|
+
and [key management](https://tools.ietf.org/html/rfc7518#section-4.1) to be supported by a JWE implementation.
|
80
|
+
|
81
|
+
Only a subset of these algorithms is implemented in this gem. Striked elements are not available:
|
82
|
+
|
83
|
+
Key management:
|
84
|
+
* RSA1_5
|
85
|
+
* RSA-OAEP (default)
|
86
|
+
* ~~RSA-OAEP-256~~
|
87
|
+
* ~~A128KW~~
|
88
|
+
* ~~A192KW~~
|
89
|
+
* ~~A256KW~~
|
90
|
+
* dir
|
91
|
+
* ~~ECDH-ES~~
|
92
|
+
* ~~ECDH-ES+A128KW~~
|
93
|
+
* ~~ECDH-ES+A192KW~~
|
94
|
+
* ~~ECDH-ES+A256KW~~
|
95
|
+
* ~~A128GCMKW~~
|
96
|
+
* ~~A192GCMKW~~
|
97
|
+
* ~~A256GCMKW~~
|
98
|
+
* ~~PBES2-HS256+A128KW~~
|
99
|
+
* ~~PBES2-HS384+A192KW~~
|
100
|
+
* ~~PBES2-HS512+A256KW~~
|
101
|
+
|
102
|
+
Encryption:
|
103
|
+
* A128CBC-HS256 (default)
|
104
|
+
* A192CBC-HS384
|
105
|
+
* A256CBC-HS512
|
106
|
+
* A128GCM
|
107
|
+
* A192GCM
|
108
|
+
* A256GCM
|
109
|
+
|
110
|
+
## License
|
111
|
+
|
112
|
+
The MIT License
|
113
|
+
|
114
|
+
* Copyright © 2016 Francesco Boffa
|
115
|
+
|
116
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
117
|
+
a copy of this software and associated documentation files (the
|
118
|
+
"Software"), to deal in the Software without restriction, including
|
119
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
120
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
121
|
+
permit persons to whom the Software is furnished to do so, subject to
|
122
|
+
the following conditions:
|
123
|
+
|
124
|
+
The above copyright notice and this permission notice shall be
|
125
|
+
included in all copies or substantial portions of the Software.
|
126
|
+
|
127
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
128
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
129
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
130
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
131
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
132
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
133
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
134
|
+
|
data/Rakefile
CHANGED
data/jwe.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = JWE::VERSION
|
8
8
|
s.summary = 'JSON Web Encryption implementation in Ruby'
|
9
9
|
s.description = 'A Ruby implementation of the RFC 7516 JSON Web Encryption (JWE) standard'
|
10
|
-
s.authors = [
|
10
|
+
s.authors = ['Francesco Boffa']
|
11
11
|
s.email = 'fra.boffa@gmail.com'
|
12
12
|
s.homepage = 'http://github.com/aomega08/jwe'
|
13
13
|
s.license = 'MIT'
|
data/lib/jwe.rb
CHANGED
@@ -10,31 +10,30 @@ require 'jwe/enc'
|
|
10
10
|
require 'jwe/zip'
|
11
11
|
|
12
12
|
module JWE
|
13
|
-
class DecodeError <
|
14
|
-
class NotImplementedError <
|
15
|
-
class BadCEK <
|
16
|
-
class InvalidData <
|
13
|
+
class DecodeError < RuntimeError; end
|
14
|
+
class NotImplementedError < RuntimeError; end
|
15
|
+
class BadCEK < RuntimeError; end
|
16
|
+
class InvalidData < RuntimeError; end
|
17
17
|
|
18
|
-
VALID_ALG = [
|
19
|
-
VALID_ENC = [
|
20
|
-
VALID_ZIP = [
|
18
|
+
VALID_ALG = ['RSA1_5', 'RSA-OAEP', 'RSA-OAEP-256', 'A128KW', 'A192KW', 'A256KW', 'dir', 'ECDH-ES', 'ECDH-ES+A128KW', 'ECDH-ES+A192KW', 'ECDH-ES+A256KW', 'A128GCMKW', 'A192GCMKW', 'A256GCMKW', 'PBES2-HS256+A128KW', 'PBES2-HS384+A192KW', 'PBES2-HS512+A256KW'].freeze
|
19
|
+
VALID_ENC = ['A128CBC-HS256', 'A192CBC-HS384', 'A256CBC-HS512', 'A128GCM', 'A192GCM', 'A256GCM'].freeze
|
20
|
+
VALID_ZIP = ['DEF'].freeze
|
21
21
|
|
22
22
|
def self.encrypt(payload, key, alg: 'RSA-OAEP', enc: 'A128GCM', zip: nil)
|
23
23
|
raise ArgumentError.new("\"#{alg}\" is not a valid alg method") unless VALID_ALG.include?(alg)
|
24
24
|
raise ArgumentError.new("\"#{enc}\" is not a valid enc method") unless VALID_ENC.include?(enc)
|
25
25
|
raise ArgumentError.new("\"#{zip}\" is not a valid zip method") unless zip.nil? || zip == '' || VALID_ZIP.include?(zip)
|
26
|
+
raise ArgumentError.new('The key must not be nil or blank') if key.nil? || (key.is_a?(String) && key.strip == '')
|
26
27
|
|
27
28
|
header = { alg: alg, enc: enc }
|
28
|
-
header[:zip] = zip if zip
|
29
|
+
header[:zip] = zip if zip && zip != ''
|
29
30
|
|
30
31
|
cipher = Enc.for(enc).new
|
31
32
|
cipher.cek = key if alg == 'dir'
|
32
33
|
|
33
|
-
if zip
|
34
|
-
payload = Zip.for(zip).new.compress(payload)
|
35
|
-
end
|
34
|
+
payload = Zip.for(zip).new.compress(payload) if zip && zip != ''
|
36
35
|
|
37
|
-
ciphertext = cipher.encrypt(payload, Base64
|
36
|
+
ciphertext = cipher.encrypt(payload, Base64.jwe_encode(header.to_json))
|
38
37
|
encrypted_cek = Alg.for(alg).new(key).encrypt(cipher.cek)
|
39
38
|
|
40
39
|
Serialization::Compact.encode(header.to_json, encrypted_cek, cipher.iv, ciphertext, cipher.tag)
|
@@ -48,6 +47,7 @@ module JWE
|
|
48
47
|
raise ArgumentError.new("\"#{header['alg']}\" is not a valid alg method") unless VALID_ALG.include?(header['alg'])
|
49
48
|
raise ArgumentError.new("\"#{header['enc']}\" is not a valid enc method") unless VALID_ENC.include?(header['enc'])
|
50
49
|
raise ArgumentError.new("\"#{header['zip']}\" is not a valid zip method") unless header['zip'].nil? || VALID_ZIP.include?(header['zip'])
|
50
|
+
raise ArgumentError.new('The key must not be nil or blank') if key.nil? || (key.is_a?(String) && key.strip == '')
|
51
51
|
|
52
52
|
cek = Alg.for(header['alg']).new(key).decrypt(enc_key)
|
53
53
|
cipher = Enc.for(header['enc']).new(cek, iv)
|
data/lib/jwe/alg.rb
CHANGED
@@ -6,7 +6,7 @@ module JWE
|
|
6
6
|
module Alg
|
7
7
|
def self.for(alg)
|
8
8
|
klass = alg.gsub(/[-\+]/, '_').downcase.sub(/^[a-z\d]*/) { $&.capitalize }
|
9
|
-
klass.gsub!(/_([a-z\d]*)/i) {
|
9
|
+
klass.gsub!(/_([a-z\d]*)/i) { Regexp.last_match(1).capitalize }
|
10
10
|
const_get(klass)
|
11
11
|
|
12
12
|
rescue NameError
|
data/lib/jwe/alg/dir.rb
CHANGED
data/lib/jwe/base64.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
module JWE
|
2
2
|
module Base64
|
3
3
|
def self.jwe_encode(payload)
|
4
|
-
::Base64.urlsafe_encode64(payload).
|
4
|
+
::Base64.urlsafe_encode64(payload).delete('=')
|
5
5
|
end
|
6
6
|
|
7
7
|
def self.jwe_decode(payload)
|
8
8
|
padlen = 4 - (payload.length % 4)
|
9
9
|
if padlen < 4
|
10
|
-
pad =
|
10
|
+
pad = '=' * padlen
|
11
11
|
payload += pad
|
12
12
|
end
|
13
13
|
::Base64.urlsafe_decode64(payload)
|
data/lib/jwe/enc.rb
CHANGED
@@ -9,7 +9,7 @@ module JWE
|
|
9
9
|
module Enc
|
10
10
|
def self.for(enc)
|
11
11
|
klass = enc.gsub(/[-\+]/, '_').downcase.sub(/^[a-z\d]*/) { $&.capitalize }
|
12
|
-
klass.gsub!(/_([a-z\d]*)/i) {
|
12
|
+
klass.gsub!(/_([a-z\d]*)/i) { Regexp.last_match(1).capitalize }
|
13
13
|
const_get(klass)
|
14
14
|
|
15
15
|
rescue NameError
|
data/lib/jwe/enc/aes_cbc_hs.rb
CHANGED
@@ -22,7 +22,7 @@ module JWE
|
|
22
22
|
|
23
23
|
to_sign = authenticated_data + iv + ciphertext + length
|
24
24
|
signature = OpenSSL::HMAC.digest(OpenSSL::Digest.new(hash_name), mac_key, to_sign)
|
25
|
-
self.tag = signature[0
|
25
|
+
self.tag = signature[0...mac_key.length]
|
26
26
|
|
27
27
|
ciphertext
|
28
28
|
end
|
@@ -33,8 +33,8 @@ module JWE
|
|
33
33
|
length = [ciphertext.length * 8].pack('Q>') # 64bit big endian
|
34
34
|
to_sign = authenticated_data + iv + ciphertext + length
|
35
35
|
signature = OpenSSL::HMAC.digest(OpenSSL::Digest.new(hash_name), mac_key, to_sign)
|
36
|
-
if signature[0
|
37
|
-
raise JWE::InvalidData.new(
|
36
|
+
if signature[0...mac_key.length] != tag
|
37
|
+
raise JWE::InvalidData.new('Authentication tag verification failed')
|
38
38
|
end
|
39
39
|
|
40
40
|
cipher.decrypt
|
@@ -43,7 +43,7 @@ module JWE
|
|
43
43
|
|
44
44
|
cipher.update(ciphertext) + cipher.final
|
45
45
|
rescue OpenSSL::Cipher::CipherError
|
46
|
-
raise JWE::InvalidData.new(
|
46
|
+
raise JWE::InvalidData.new('Invalid ciphertext or authentication tag')
|
47
47
|
end
|
48
48
|
|
49
49
|
def iv
|
@@ -55,11 +55,11 @@ module JWE
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def mac_key
|
58
|
-
cek[0
|
58
|
+
cek[0...key_length / 2]
|
59
59
|
end
|
60
60
|
|
61
61
|
def enc_key
|
62
|
-
cek[key_length / 2
|
62
|
+
cek[key_length / 2..-1]
|
63
63
|
end
|
64
64
|
|
65
65
|
def cipher
|
@@ -69,7 +69,7 @@ module JWE
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def tag
|
72
|
-
@tag ||
|
72
|
+
@tag || ''
|
73
73
|
end
|
74
74
|
|
75
75
|
def self.included(base)
|
data/lib/jwe/enc/aes_gcm.rb
CHANGED
@@ -35,7 +35,7 @@ module JWE
|
|
35
35
|
|
36
36
|
cipher.update(ciphertext) + cipher.final
|
37
37
|
rescue OpenSSL::Cipher::CipherError
|
38
|
-
raise JWE::InvalidData.new(
|
38
|
+
raise JWE::InvalidData.new('Invalid ciphertext or authentication tag')
|
39
39
|
end
|
40
40
|
|
41
41
|
def iv
|
@@ -53,7 +53,7 @@ module JWE
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def tag
|
56
|
-
@tag ||
|
56
|
+
@tag || ''
|
57
57
|
end
|
58
58
|
|
59
59
|
def self.included(base)
|
@@ -2,7 +2,7 @@ module JWE
|
|
2
2
|
module Serialization
|
3
3
|
class Compact
|
4
4
|
def self.encode(header, encrypted_cek, iv, ciphertext, tag)
|
5
|
-
[
|
5
|
+
[header, encrypted_cek, iv, ciphertext, tag].map { |piece| JWE::Base64.jwe_encode(piece) }.join '.'
|
6
6
|
end
|
7
7
|
|
8
8
|
def self.decode(payload)
|
data/lib/jwe/version.rb
CHANGED
data/lib/jwe/zip.rb
CHANGED
@@ -4,7 +4,7 @@ module JWE
|
|
4
4
|
module Zip
|
5
5
|
def self.for(zip)
|
6
6
|
klass = zip.gsub(/[-\+]/, '_').downcase.sub(/^[a-z\d]*/) { $&.capitalize }
|
7
|
-
klass.gsub!(/_([a-z\d]*)/i) {
|
7
|
+
klass.gsub!(/_([a-z\d]*)/i) { Regexp.last_match(1).capitalize }
|
8
8
|
const_get(klass)
|
9
9
|
|
10
10
|
rescue NameError
|
data/spec/jwe/base64_spec.rb
CHANGED
@@ -5,22 +5,22 @@ module JWE
|
|
5
5
|
describe '.jwe_encode' do
|
6
6
|
it 'encodes the payload using the urlsafe encoding' do
|
7
7
|
# "me?" encodes to "bWU/" in standard encoding
|
8
|
-
expect(Base64.jwe_encode(
|
8
|
+
expect(Base64.jwe_encode('me?')).to_not include '/'
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'strips the standard padding' do
|
12
|
-
expect(Base64.jwe_encode(
|
12
|
+
expect(Base64.jwe_encode('a')).to_not end_with '='
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
describe '.jwe_decode' do
|
17
17
|
it 'decodes the payload using the urlsafe encoding' do
|
18
18
|
# "me?" encodes to "bWU/" in standard encoding
|
19
|
-
expect(Base64.jwe_decode(
|
19
|
+
expect(Base64.jwe_decode('bWU_')).to eq 'me?'
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'fixes the padding' do
|
23
|
-
expect(Base64.jwe_decode(
|
23
|
+
expect(Base64.jwe_decode('YQ')).to eq 'a'
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/spec/jwe/enc_spec.rb
CHANGED
@@ -116,7 +116,7 @@ gcm.each do |group|
|
|
116
116
|
context 'when the tag is not valid' do
|
117
117
|
it 'raises an error' do
|
118
118
|
enc = klass.new(key, group[:iv])
|
119
|
-
enc.tag =
|
119
|
+
enc.tag = 'random'
|
120
120
|
expect { enc.decrypt(group[:helloworld], '') }.to raise_error(JWE::InvalidData)
|
121
121
|
end
|
122
122
|
end
|
@@ -132,7 +132,7 @@ gcm.each do |group|
|
|
132
132
|
it 'raises an error' do
|
133
133
|
enc = klass.new(key, group[:iv])
|
134
134
|
enc.tag = group[:tag]
|
135
|
-
expect { enc.decrypt(
|
135
|
+
expect { enc.decrypt('random', '') }.to raise_error(JWE::InvalidData)
|
136
136
|
end
|
137
137
|
end
|
138
138
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
describe JWE::Serialization::Compact do
|
2
2
|
describe '#encode' do
|
3
3
|
it 'returns components base64ed and joined with a dot' do
|
4
|
-
components =
|
4
|
+
components = %w(a b c d e)
|
5
5
|
expect(JWE::Serialization::Compact.encode(*components)).to eq 'YQ.Yg.Yw.ZA.ZQ'
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
9
|
describe '#decode' do
|
10
10
|
it 'returns an array with the 5 components' do
|
11
|
-
expect(JWE::Serialization::Compact.decode('YQ.Yg.Yw.ZA.ZQ')).to eq
|
11
|
+
expect(JWE::Serialization::Compact.decode('YQ.Yg.Yw.ZA.ZQ')).to eq %w(a b c d e)
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'raises an error when passed a badly formatted payload' do
|
data/spec/jwe/zip_spec.rb
CHANGED
@@ -15,7 +15,7 @@ end
|
|
15
15
|
describe JWE::Zip::Def do
|
16
16
|
it 'deflates and inflates to original payload' do
|
17
17
|
deflate = JWE::Zip::Def.new
|
18
|
-
deflated = deflate.compress(
|
19
|
-
expect(deflate.decompress(deflated)).to eq
|
18
|
+
deflated = deflate.compress('hello world')
|
19
|
+
expect(deflate.decompress(deflated)).to eq 'hello world'
|
20
20
|
end
|
21
21
|
end
|
data/spec/jwe_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
describe JWE do
|
2
|
-
let(:plaintext) {
|
2
|
+
let(:plaintext) { 'The true sign of intelligence is not knowledge but imagination.' }
|
3
3
|
let(:rsa_key) { OpenSSL::PKey::RSA.new File.read(File.dirname(__FILE__) + '/keys/rsa.pem') }
|
4
4
|
let(:password) { SecureRandom.random_bytes(64) }
|
5
5
|
|
@@ -42,19 +42,49 @@ describe JWE do
|
|
42
42
|
|
43
43
|
it 'raises when decoding a bad alg' do
|
44
44
|
hdr = { alg: 'TEST', enc: 'A128GCM' }
|
45
|
-
payload = JWE::Base64.jwe_encode(hdr.to_json) +
|
45
|
+
payload = JWE::Base64.jwe_encode(hdr.to_json) + '.QY.QY.QY.QY'
|
46
46
|
expect { JWE.decrypt(payload, rsa_key) }.to raise_error(ArgumentError)
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'raises when decoding a bad enc' do
|
50
50
|
hdr = { alg: 'A192CBC-HS384', enc: 'TEST' }
|
51
|
-
payload = JWE::Base64.jwe_encode(hdr.to_json) +
|
51
|
+
payload = JWE::Base64.jwe_encode(hdr.to_json) + '.QY.QY.QY.QY'
|
52
52
|
expect { JWE.decrypt(payload, rsa_key) }.to raise_error(ArgumentError)
|
53
53
|
end
|
54
54
|
|
55
55
|
it 'raises when decoding a bad zip' do
|
56
56
|
hdr = { alg: 'A192CBC-HS384', enc: 'A128GCM', zip: 'TEST' }
|
57
|
-
payload = JWE::Base64.jwe_encode(hdr.to_json) +
|
57
|
+
payload = JWE::Base64.jwe_encode(hdr.to_json) + '.QY.QY.QY.QY'
|
58
58
|
expect { JWE.decrypt(payload, rsa_key) }.to raise_error(ArgumentError)
|
59
59
|
end
|
60
|
+
|
61
|
+
it 'raises when encrypting with a nil key' do
|
62
|
+
expect { JWE.encrypt(plaintext, nil) }.to raise_error(ArgumentError)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'raises when decrypting with a nil key' do
|
66
|
+
hdr = { alg: 'A192CBC-HS384', enc: 'A128GCM', zip: 'TEST' }
|
67
|
+
payload = JWE::Base64.jwe_encode(hdr.to_json) + '.QY.QY.QY.QY'
|
68
|
+
expect { JWE.decrypt(payload, nil) }.to raise_error(ArgumentError)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'raises when encrypting with a blank key' do
|
72
|
+
expect { JWE.encrypt(plaintext, " \t \n ") }.to raise_error(ArgumentError)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'raises when decrypting with a blank key' do
|
76
|
+
hdr = { alg: 'A192CBC-HS384', enc: 'A128GCM', zip: 'TEST' }
|
77
|
+
payload = JWE::Base64.jwe_encode(hdr.to_json) + '.QY.QY.QY.QY'
|
78
|
+
expect { JWE.decrypt(payload, " \t \n ") }.to raise_error(ArgumentError)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'raises when encrypting with a nil key with `dir` algorithm' do
|
82
|
+
expect { JWE.encrypt(plaintext, nil, alg: 'dir') }.to raise_error(ArgumentError)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'raises when decrypting with a nil key with `dir` algorithm' do
|
86
|
+
hdr = { alg: 'A192CBC-HS384', enc: 'A128GCM', zip: 'TEST' }
|
87
|
+
payload = JWE::Base64.jwe_encode(hdr.to_json) + '.QY.QY.QY.QY'
|
88
|
+
expect { JWE.decrypt(payload, nil, alg: 'dir') }.to raise_error(ArgumentError)
|
89
|
+
end
|
60
90
|
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.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Francesco Boffa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -65,6 +65,7 @@ files:
|
|
65
65
|
- ".travis.yml"
|
66
66
|
- Gemfile
|
67
67
|
- LICENSE.md
|
68
|
+
- README.md
|
68
69
|
- Rakefile
|
69
70
|
- jwe.gemspec
|
70
71
|
- lib/jwe.rb
|
@@ -114,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
115
|
version: '0'
|
115
116
|
requirements: []
|
116
117
|
rubyforge_project:
|
117
|
-
rubygems_version: 2.4.
|
118
|
+
rubygems_version: 2.4.8
|
118
119
|
signing_key:
|
119
120
|
specification_version: 4
|
120
121
|
summary: JSON Web Encryption implementation in Ruby
|