json-jwt 1.4.0 → 1.5.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.

Potentially problematic release.


This version of json-jwt might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6817c45c39a6ae6f9240df8b7edb8d407ef79744
4
- data.tar.gz: 8f97ad80b2d8fda2732b8cbbf8166b9ca8bca404
3
+ metadata.gz: e593ec307b6ef4d7c0f401221c585c615c86c918
4
+ data.tar.gz: 4068c3885a7f8417b577f0b5413f567f94612488
5
5
  SHA512:
6
- metadata.gz: 1cc01ddbca74f1dd13cc054e5b3e2d1d9242191309526a29c1c1e75e5c5f08d70cb79c208dd4afb1b7dc948bed2b85adef25f5c8a9314ec0f5ff256a9cbdd0b2
7
- data.tar.gz: 17b0980e989fd63dcf0ee5ee48dd8cc44d38ead751ecf6523e2ea4ed7d820b520be0502d0fb9265d73c330bf0aebd8c7794b610d69373526bfc3d14a4803fe4a
6
+ metadata.gz: b15ef784c658a73d9cf7e5d79fc55966008d08c87f8d1b3b4a4384fd3017a410f490e008ecdbd12d4fdd2347c337533857b66db5569d293c9622a90cbcd1604c
7
+ data.tar.gz: 33b50220dfd570e1982d98a3e1a1ee30f52e4d2a3bfb49b616ba24c60463dcac23554c6fc1cbb3da3ee4f7a684f81c6101c7a84839bc727ca578cff2d0d7c313
data/README.md CHANGED
@@ -14,183 +14,42 @@ gem install json-jwt
14
14
 
15
15
  * View Source on GitHub (https://github.com/nov/json-jwt)
16
16
  * Report Issues on GitHub (https://github.com/nov/json-jwt/issues)
17
+ * Documentation on GitHub (https://github.com/nov/json-jwt/wiki)
17
18
 
18
19
  ## Examples
19
20
 
20
- ### JWT, JWS and JWE
21
-
22
- #### Encoding
23
-
24
21
  ```ruby
25
22
  require 'json/jwt'
26
23
 
24
+ private_key = OpenSSL::PKey::RSA.new <<-PEM
25
+ -----BEGIN RSA PRIVATE KEY-----
26
+ MIIEpAIBAAKCAQEAyBKIFSH8dP6bDkGBziB6RXTTfZVTaaNSWNtIzDmgRFi6FbLo
27
+ :
28
+ -----END RSA PRIVATE KEY-----
29
+ PEM
30
+
31
+ public_key = OpenSSL::PKey::RSA.new <<-PEM
32
+ -----BEGIN PUBLIC KEY-----
33
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyBKIFSH8dP6bDkGBziB6
34
+ :
35
+ -----END PUBLIC KEY-----
36
+ PEM
37
+
38
+ # Sign & Encode
27
39
  claim = {
28
40
  iss: 'nov',
29
41
  exp: 1.week.from_now,
30
42
  nbf: Time.now
31
43
  }
44
+ jws = JSON::JWT.new(claim).sign(private_key, :RS256)
45
+ jws.to_s
32
46
 
33
- # No signature, no encryption
34
- jwt = JSON::JWT.new(claim).to_s
35
-
36
- # With signiture, no encryption
37
- jws = JSON::JWT.new(claim).sign(key, algorithm) # algorithm is optional. default HS256
38
- jws.to_s # => header.payload.signature
39
- jws.to_json(syntax: :general) # => General JWS JSON Serialization
40
- jws.to_json(syntax: :flatten) # => Flattened JWS JSON Serialization
41
-
42
- # With signature & encryption
43
- jwe = jws.encrypt(key, algorithm, encryption_method) # algorithm & encryption_method are optional. default RSA1_5 & A128CBC-HS256
44
- jwe.to_s # => header.encrypted_key.iv.cipher_text.authentication_tag
45
- ```
46
-
47
- Supported `key` are
48
- * `String`
49
- * `OpenSSL::PKey::RSA`
50
- * `OpenSSL::PKey::EC`
51
- * `JSON::JWK`
52
- * `JSON::JWK::Set` # NOTE: proper `JSON::JWK` in the set will be selected by `kid` in the header.
53
-
54
- Supported `algorithm` are
55
-
56
- For JWS
57
- * `HS256`
58
- * `HS384`
59
- * `HS512`
60
- * `RS256`
61
- * `RS384`
62
- * `RS512`
63
- * `ES256`
64
- * `ES384`
65
- * `ES512`
66
-
67
- For JWE
68
- * `RSA1_5`
69
- * `RSA-OAEP`
70
- * `dir`
71
-
72
- Supported `encryption_method` are
73
- * `A128GCM`
74
- * `A256GCM`
75
- * `A128CBC-HS256`
76
- * `A256CBC-HS512`
77
-
78
- #### Decoding
79
-
80
- ```ruby
47
+ # Decode & Verify
81
48
  input = "jwt_header.jwt_claims.jwt_signature"
82
- JSON::JWT.decode(input, key)
83
- ```
84
-
85
- `input` can be JSON, in that case, it's handled as General/Flattened JWS JSON Serialization.
86
-
87
- NOTE: General JWS JSON Serialization with multiple signatures aren't supported.
88
-
89
- Supported `key` are
90
- * `String`
91
- * `OpenSSL::PKey::RSA`
92
- * `OpenSSL::PKey::EC`
93
- * `JSON::JWK`
94
- * `JSON::JWK::Set` # NOTE: proper `JSON::JWK` in the set will be selected by `kid` in the header.
95
- * `:skip_verification` # NOTE: skip signature verification
96
-
97
- ### JWK
98
-
99
- `JSON::JWK.new` accepts these instances as key inputs
100
- * `String` # NOTE: for shared key (kty=oct)
101
- * `OpenSSL::PKey::RSA`
102
- * `OpenSSL::PKey::EC`
103
- * `JSON::JWK`
104
- * `Hash`
105
-
106
- This gem also defines
107
- * `OpenSSL::PKey::RSA#to_jwk`
108
- * `OpenSSL::PKey::EC#to_jwk`
109
-
110
- #### RSA
111
-
112
- ```ruby
113
- k = OpenSSL::PKey::RSA.new(2048)
114
-
115
- k.to_jwk # NOTE: same with `JSON::JWK.new(k)`
116
- # => JSON::JWK (private key)
117
-
118
- k.public_key.to_jwk
119
- # => JSON::JWK (public key)
49
+ JSON::JWT.decode(input, public_key)
120
50
  ```
121
51
 
122
- ```ruby
123
- jwk = JSON::JWK.new(
124
- kty: "RSA",
125
- e: "AQAB",
126
- n: "0OIOijENzP0AXnxP-X8Dnazt3m4NTamfNsSCkH4xzgZAJj2Eur9-zmq9IukwN37lIrm3oAE6lL4ytNkv-DQpAivKLE8bh4c9qlB9o32VWyg-mg-2af-JlfGXYoaCW2GDMOV6EKqHBxE0x1EI0tG4gcNwO6A_kYtK6_ACgTQudWz_gnPrL-QCunjIMbbrK9JqgMZhgMARMQpB-j8oet2FFsEcquR5MWtBeAn7qC1AD2ya0EmzplZJP6oCka_VVuxAnyWfRGA0bzCBRIVbcGUXVNIXpRtA_4960e7AlGfMSA-ofN-vo7v0CMkA8BwpZHai9CAJ-cTCX1AVbov83LVIWw",
127
- d: "BZCgNopMBdQPuHSzZMA_hmnfBHgGHrWQKlNd7x-NkCGWf-5PpPIJHNK3K0DvKetVi3FLNRYTS3ctvqeyoXgyR36HKlsJLrkpqWnvjvV_jygpUs1sXLKUJcyD7foLawfUCO90KxF_-24367967rLrqXldehkw2F3Ppy2Dw5FyU2qBqcpLeruBt6-UdMmBufzNQLisPJ67vhCTVrTNaHDDeCK2gHI3gqsnnbzOMS45VknmFOgKUp1C8GZu5BsT-AdDApEtY-DRZqnr6BxZv4-hG5OdEUA4_LCaI6JwlaAzv0Z74jpBZDC73cXWKJPgVuhARZcll5cexB2_EpgZDB6akQ",
128
- p: "6GFVNgaXcW39NG-sRqKPzFtz1usfAkdCydPmfZirfHRhSh3OojX3Glbe7BI_SRSOLc2d2xw2_ZwKRlruY44aGEf4s5gD_nKgq2QS-1cA5uNAU91wRtY2rdoAuCnk2BX3WTZPnzyxkokFY0S0R_9IpJhRz72ggxYyhx0ymRUBIWc",
129
- q: "5h1QX2JWLbcIT_cfrkmMoES1z06Fu88MLORYppiRDqkXl3CJFxKFtKJtDPLTf0MeTFexh81V52Ztsd8UttPInyDl9l5T0AOy8NmqHKqjI1063uy4bnHWetN7ovHftc_TOlnldAoQh9bmhZAhEyGlwa5Kros2YD2amIgDhcOmRO0"
130
- )
131
- jwk.to_key
132
- # => OpenSSL::PKey::RSA (private key)
133
-
134
- jwk = JSON::JWK.new(
135
- kty: "RSA",
136
- e: "AQAB",
137
- n: "0OIOijENzP0AXnxP-X8Dnazt3m4NTamfNsSCkH4xzgZAJj2Eur9-zmq9IukwN37lIrm3oAE6lL4ytNkv-DQpAivKLE8bh4c9qlB9o32VWyg-mg-2af-JlfGXYoaCW2GDMOV6EKqHBxE0x1EI0tG4gcNwO6A_kYtK6_ACgTQudWz_gnPrL-QCunjIMbbrK9JqgMZhgMARMQpB-j8oet2FFsEcquR5MWtBeAn7qC1AD2ya0EmzplZJP6oCka_VVuxAnyWfRGA0bzCBRIVbcGUXVNIXpRtA_4960e7AlGfMSA-ofN-vo7v0CMkA8BwpZHai9CAJ-cTCX1AVbov83LVIWw"
138
- )
139
- jwk.to_key
140
- # => OpenSSL::PKey::RSA (public key)
141
- ```
142
-
143
- #### EC
144
-
145
- ```ruby
146
- k = OpenSSL::PKey::EC.new('prime256v1').generate_key
147
-
148
- k.to_jwk
149
- # => JSON::JWK (private key)
150
-
151
- k.private_key = nil
152
- k.to_jwk
153
- # => JSON::JWK (public key)
154
- ```
155
-
156
- ```ruby
157
- jwk = JSON::JWK.new(
158
- kty: "EC",
159
- crv: "P-256",
160
- x: "D4L5V9QocZvfuEEGfGD5YCEbIcXR-KfF7RqqZUaovJ8",
161
- y: "VX0T94KUo0YkhuvT2q0MXMOTtfaIjDS4fb9ii54g4gU",
162
- d: "MCOTV6Ncg7KTuGh1hTa029ZVkqdlaXaYnfLSkZjJ_uE"
163
- )
164
- jwk.to_key
165
- # => OpenSSL::PKey::EC (private key)
166
-
167
- jwk = JSON::JWK.new(
168
- kty: "EC",
169
- crv: "P-256",
170
- x: "D4L5V9QocZvfuEEGfGD5YCEbIcXR-KfF7RqqZUaovJ8",
171
- y: "VX0T94KUo0YkhuvT2q0MXMOTtfaIjDS4fb9ii54g4gU"
172
- )
173
- jwk.to_key
174
- # => OpenSSL::PKey::EC (public key)
175
- ```
176
-
177
- #### oct
178
-
179
- NOTE: no `String#to_jwk` is defined for now.
180
-
181
- ```ruby
182
- JSON::JWK.new 'secret'
183
- # => JSON::JWK
184
- ```
185
-
186
- ```ruby
187
- jwk = JSON::JWK.new(
188
- kty: "oct",
189
- k: "secret"
190
- )
191
- jwk.to_key
192
- # => String
193
- ```
52
+ For more details, read [Documentation Wiki](https://github.com/nov/json-jwt/wiki).
194
53
 
195
54
  ## Note on Patches/Pull Requests
196
55
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.0
1
+ 1.5.0
@@ -1,11 +1,46 @@
1
1
  require 'securecompare'
2
2
 
3
3
  module JSON
4
- class JOSE < JWT
5
- include SecureCompare
4
+ module JOSE
5
+ extend ActiveSupport::Concern
6
6
 
7
- def content_type
8
- 'application/jose'
7
+ included do
8
+ extend ClassMethods
9
+ include SecureCompare
10
+ register_header_keys :alg, :jku, :jwk, :x5u, :x5t, :x5c, :kid, :typ, :cty, :crit
11
+ alias_method :algorithm, :alg
12
+
13
+ attr_accessor :header
14
+ def header
15
+ @header ||= {}
16
+ end
17
+
18
+ def content_type
19
+ @content_type ||= 'application/jose'
20
+ end
21
+ end
22
+
23
+ module ClassMethods
24
+ def register_header_keys(*keys)
25
+ keys.each do |header_key|
26
+ define_method header_key do
27
+ self.header[header_key]
28
+ end
29
+ define_method "#{header_key}=" do |value|
30
+ self.header[header_key] = value
31
+ end
32
+ end
33
+ end
34
+
35
+ def decode(input, key_or_secret = nil)
36
+ if input.is_a? Hash
37
+ decode_json_serialized input, key_or_secret
38
+ else
39
+ decode_compact_serialized input, key_or_secret
40
+ end
41
+ rescue MultiJson::DecodeError
42
+ raise JWT::InvalidFormat.new("Invalid JSON Format")
43
+ end
9
44
  end
10
45
  end
11
46
  end
@@ -2,13 +2,15 @@ require 'securerandom'
2
2
  require 'bindata'
3
3
 
4
4
  module JSON
5
- class JWE < JOSE
5
+ class JWE
6
6
  class InvalidFormat < JWT::InvalidFormat; end
7
7
  class DecryptionFailed < JWT::VerificationFailed; end
8
8
  class UnexpectedAlgorithm < JWT::UnexpectedAlgorithm; end
9
9
 
10
10
  NUM_OF_SEGMENTS = 5
11
11
 
12
+ include JOSE
13
+
12
14
  attr_accessor(
13
15
  :public_key_or_secret, :private_key_or_secret,
14
16
  :plain_text, :cipher_text, :authentication_tag, :iv, :auth_data,
@@ -22,10 +24,6 @@ module JSON
22
24
  self.plain_text = input.to_s
23
25
  end
24
26
 
25
- def content_type
26
- 'application/jose'
27
- end
28
-
29
27
  def encrypt!(public_key_or_secret)
30
28
  self.public_key_or_secret = public_key_or_secret
31
29
  cipher.encrypt
@@ -67,7 +65,7 @@ module JSON
67
65
  ciphertext: UrlSafeBase64.encode64(cipher_text),
68
66
  tag: UrlSafeBase64.encode64(authentication_tag)
69
67
  }
70
- when :flattened
68
+ else
71
69
  {
72
70
  protected: UrlSafeBase64.encode64(header.to_json),
73
71
  encrypted_key: UrlSafeBase64.encode64(jwe_encrypted_key),
@@ -75,8 +73,6 @@ module JSON
75
73
  ciphertext: UrlSafeBase64.encode64(cipher_text),
76
74
  tag: UrlSafeBase64.encode64(authentication_tag)
77
75
  }
78
- else
79
- super
80
76
  end
81
77
  end
82
78
 
@@ -1,5 +1,5 @@
1
1
  module JSON
2
- class JWS < JOSE
2
+ class JWS < JWT
3
3
  class InvalidFormat < JWT::InvalidFormat; end
4
4
  class VerificationFailed < JWT::VerificationFailed; end
5
5
  class UnexpectedAlgorithm < JWT::UnexpectedAlgorithm; end
@@ -3,32 +3,21 @@ require 'url_safe_base64'
3
3
  require 'multi_json'
4
4
  require 'active_support'
5
5
  require 'active_support/core_ext'
6
+ require 'json/jose'
6
7
 
7
8
  module JSON
8
9
  class JWT < ActiveSupport::HashWithIndifferentAccess
9
- attr_accessor :header, :signature
10
+ attr_accessor :signature
10
11
 
11
12
  class Exception < StandardError; end
12
13
  class InvalidFormat < Exception; end
13
14
  class VerificationFailed < Exception; end
14
15
  class UnexpectedAlgorithm < VerificationFailed; end
15
16
 
16
- class << self
17
- def register_header_keys(*keys)
18
- keys.each do |header_key|
19
- define_method header_key do
20
- self.header[header_key]
21
- end
22
- define_method "#{header_key}=" do |value|
23
- self.header[header_key] = value
24
- end
25
- end
26
- end
27
- end
28
- register_header_keys :alg, :jku, :jwk, :x5u, :x5t, :x5c, :kid, :typ, :cty, :crit
29
- alias_method :algorithm, :alg
17
+ include JOSE
30
18
 
31
19
  def initialize(claims = {})
20
+ @content_type = 'application/jwt'
32
21
  self.typ = :JWT
33
22
  self.alg = :none
34
23
  [:exp, :nbf, :iat].each do |key|
@@ -37,14 +26,6 @@ module JSON
37
26
  update claims
38
27
  end
39
28
 
40
- def content_type
41
- 'application/jwt'
42
- end
43
-
44
- def header
45
- @header ||= {}
46
- end
47
-
48
29
  def sign(private_key_or_secret, algorithm = :HS256)
49
30
  jws = JWS.new self
50
31
  jws.alg = algorithm
@@ -97,16 +78,6 @@ module JSON
97
78
  end
98
79
 
99
80
  class << self
100
- def decode(input, key_or_secret = nil)
101
- if input.is_a? Hash
102
- decode_json_serialized input, key_or_secret
103
- else
104
- decode_compact_serialized input, key_or_secret
105
- end
106
- rescue MultiJson::DecodeError
107
- raise InvalidFormat.new("Invalid JSON Format")
108
- end
109
-
110
81
  def decode_compact_serialized(jwt_string, key_or_secret)
111
82
  case jwt_string.count('.') + 1
112
83
  when JWS::NUM_OF_SEGMENTS
@@ -132,7 +103,6 @@ module JSON
132
103
  end
133
104
  end
134
105
 
135
- require 'json/jose'
136
106
  require 'json/jws'
137
107
  require 'json/jwe'
138
108
  require 'json/jwk'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json-jwt
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nov matake
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-08 00:00:00.000000000 Z
11
+ date: 2015-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json