Class: JOSE::JWT
- Inherits:
-
Struct
- Object
- Struct
- JOSE::JWT
- Defined in:
- lib/jose/jwt.rb
Overview
JWT stands for JSON Web Token which is defined in RFC 7519.
Encryption Examples
All of the example keys generated below can be found here: https://gist.github.com/potatosalad/dd140560b2bdbdab886d
See JOSE::JWE for more Encryption examples.
A128GCM
jwk_oct128 = JOSE::JWK.from_oct(([0]*16).pack('C*'))
jwt = { "test" => true }
# A128GCM
encrypted_a128gcm = JOSE::JWT.encrypt(jwk_oct128, { "alg" => "dir", "enc" => "A128GCM" }, jwt).compact
# => "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4R0NNIiwidHlwIjoiSldUIn0..yKs3KxBPBsp60bVv.lYrRQrT8GQQMG2OFCA.Z6GQkHT6K6VWxkOJBLFt3g"
JOSE::JWT.decrypt(jwk_oct128, encrypted_a128gcm)
# => [#<struct JOSE::JWT fields=JOSE::Map["test" => true]>,
# #<struct JOSE::JWE
# alg=#<JOSE::JWE::ALG_dir:0x007fd81c1023d0>,
# enc=#<struct JOSE::JWE::ENC_AES_GCM cipher_name="aes-128-gcm", bits=128, cek_len=16, iv_len=12>,
# zip=nil,
# fields=JOSE::Map["typ" => "JWT"]>]
Signature Examples
All of the example keys generated below can be found here: https://gist.github.com/potatosalad/925a8b74d85835e285b9
See JOSE::JWS for more Signature examples. For security purposes, JOSE::JWT.verify_strict is recommended over JOSE::JWT.verify.
HS256
# let's generate the key we'll use below and define our jwt
jwk_hs256 = JOSE::JWK.generate_key([:oct, 16])
jwt = { "test" => true }
# HS256
signed_hs256 = JOSE::JWT.sign(jwk_hs256, { "alg" => "HS256" }, jwt).compact
# => "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0Ijp0cnVlfQ.XYsFJDhfBZCAKnEZjR0WWd1l1ZPDD4bYpZYMHizexfQ"
# verify_strict is recommended over verify
JOSE::JWT.verify_strict(jwk_hs256, ["HS256"], signed_hs256)
# => [true,
# #<struct JOSE::JWT fields=JOSE::Map["test" => true]>,
# #<struct JOSE::JWS
# alg=#<struct JOSE::JWS::ALG_HMAC hmac=OpenSSL::Digest::SHA256>,
# b64=nil,
# fields=JOSE::Map["typ" => "JWT"]>]
# verify returns the same thing without "alg" whitelisting
JOSE::JWT.verify(jwk_hs256, signed_hs256)
# => [true,
# #<struct JOSE::JWT fields=JOSE::Map["test" => true]>,
# #<struct JOSE::JWS
# alg=#<struct JOSE::JWS::ALG_HMAC hmac=OpenSSL::Digest::SHA256>,
# b64=nil,
# fields=JOSE::Map["typ" => "JWT"]>]
# the default signing algorithm is also "HS256" based on the type of jwk used
signed_hs256 == JOSE::JWT.sign(jwk_hs256, jwt).compact
# => true
Instance Attribute Summary collapse
-
#fields ⇒ Object
Returns the value of attribute fields.
Class Method Summary collapse
-
.decrypt(jwk, encrypted) ⇒ [JOSE::JWT, JOSE::JWE]
Decrypts an encrypted JOSE::JWT using the
jwk
. -
.encrypt(jwk, jwe, jwt = nil) ⇒ JOSE::EncryptedMap
Encrypts a JOSE::JWT using the
jwk
and the default block encryptor algorithmjwe
for the key type. -
.from(object, modules = {}) ⇒ JOSE::JWT+
Converts a binary or map into a JOSE::JWT.
-
.from_binary(object, modules = {}) ⇒ JOSE::JWT+
Converts a binary into a JOSE::JWT.
-
.from_file(file, modules = {}) ⇒ JOSE::JWT
Reads file and calls JWT.from_binary to convert into a JOSE::JWT.
-
.from_map(object, modules = {}) ⇒ JOSE::JWT+
Converts a map into a JOSE::JWT.
-
.merge(left, right) ⇒ JOSE::JWT
Merges map on right into map on left.
-
.peek_payload(signed) ⇒ JOSE::Map
Returns the decoded payload portion of a signed binary or map without verifying the signature.
-
.peek_protected(signed) ⇒ String
Returns the decoded protected portion of a signed binary or map without verifying the signature.
-
.peek_signature(signed) ⇒ String
Returns the decoded signature portion of a signed binary or map without verifying the signature.
-
.sign(jwk, jws, jwt = nil, header = nil) ⇒ JOSE::SignedMap
Signs a JOSE::JWT using the
jwk
and the default signer algorithmjws
for the key type. -
.to_binary(jwt) ⇒ String+
Converts a JOSE::JWT into a binary.
-
.to_file(jwt, file) ⇒ Fixnum
Calls JWT.to_binary on a JOSE::JWT and then writes the binary to
file
. -
.to_map(jwt) ⇒ JOSE::Map+
Converts a JOSE::JWT into a map.
-
.verify(jwk, signed) ⇒ [Boolean, JOSE::JWT, JOSE::JWS]
Verifies the
signed
using thejwk
and calls JOST::JWT.from on the payload. -
.verify_strict(jwk, allow, signed) ⇒ [Boolean, (JOSE::JWT, String), (JOSE::JWS, JOSE::Map)]
Verifies the
signed
using thejwk
, whitelists the"alg"
usingallow
, and calls JOST::JWT.from on the payload.
Instance Method Summary collapse
-
#encrypt(jwk, jwe = nil) ⇒ JOSE::EncryptedMap
Encrypts a JOSE::JWT using the
jwk
and thejwe
algorithm. -
#merge(object) ⇒ JOSE::JWT
Merges object into current map.
-
#sign(jwk, jws = nil, header = nil) ⇒ JOSE::SignedMap
Signs a JOSE::JWT using the
jwk
and thejws
algorithm. -
#to_binary ⇒ String
Converts a JOSE::JWT into a binary.
-
#to_file(file) ⇒ Fixnum
Calls #to_binary on a JOSE::JWT and then writes the binary to
file
. -
#to_map ⇒ JOSE::Map
Converts a JOSE::JWT into a map.
Instance Attribute Details
#fields ⇒ Object
Returns the value of attribute fields
65 66 67 |
# File 'lib/jose/jwt.rb', line 65 def fields @fields end |
Class Method Details
.decrypt(jwk, encrypted) ⇒ [JOSE::JWT, JOSE::JWE]
Decrypts an encrypted JOSE::JWT using the jwk
.
191 192 193 194 |
# File 'lib/jose/jwt.rb', line 191 def self.decrypt(jwk, encrypted) decrypted, jwe = JOSE::JWK.block_decrypt(jwk, encrypted) return from_binary(decrypted), jwe end |
.encrypt(jwk, jwe, jwt = nil) ⇒ JOSE::EncryptedMap
Encrypts a JOSE::JWT using the jwk
and the default block encryptor algorithm jwe
for the key type.
202 203 204 205 206 207 208 |
# File 'lib/jose/jwt.rb', line 202 def self.encrypt(jwk, jwe, jwt = nil) if jwt.nil? jwt = jwe jwe = nil end return from(jwt).encrypt(jwk, jwe) end |
.from(object, modules = {}) ⇒ JOSE::JWT+
80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/jose/jwt.rb', line 80 def self.from(object, modules = {}) case object when JOSE::Map, Hash return from_map(object, modules) when String return from_binary(object, modules) when JOSE::JWT return object when Array return object.map { |obj| from(obj, modules) } else raise ArgumentError, "'object' must be a Hash, String, JOSE::JWT, or Array" end end |
.from_binary(object, modules = {}) ⇒ JOSE::JWT+
Converts a binary into a JOSE::JWT.
99 100 101 102 103 104 105 106 107 108 |
# File 'lib/jose/jwt.rb', line 99 def self.from_binary(object, modules = {}) case object when String return from_map(JOSE.decode(object), modules) when Array return object.map { |obj| from_binary(obj, modules) } else raise ArgumentError, "'object' must be a String or Array" end end |
.from_file(file, modules = {}) ⇒ JOSE::JWT
Reads file and calls from_binary to convert into a JOSE::JWT.
114 115 116 |
# File 'lib/jose/jwt.rb', line 114 def self.from_file(file, modules = {}) return from_binary(File.binread(file), modules) end |
.from_map(object, modules = {}) ⇒ JOSE::JWT+
Converts a map into a JOSE::JWT.
122 123 124 125 126 127 128 129 130 131 |
# File 'lib/jose/jwt.rb', line 122 def self.from_map(object, modules = {}) case object when JOSE::Map, Hash return from_fields(JOSE::JWT.new(JOSE::Map.new(object)), modules) when Array return object.map { |obj| from_map(obj, modules) } else raise ArgumentError, "'object' must be a Hash or Array" end end |
.merge(left, right) ⇒ JOSE::JWT
Merges map on right into map on left.
236 237 238 |
# File 'lib/jose/jwt.rb', line 236 def self.merge(left, right) return from(left).merge(right) end |
.peek_payload(signed) ⇒ JOSE::Map
266 267 268 |
# File 'lib/jose/jwt.rb', line 266 def self.peek_payload(signed) return JOSE::Map.new(JOSE.decode(JOSE::JWS.peek_payload(signed))) end |
.peek_protected(signed) ⇒ String
Returns the decoded protected portion of a signed binary or map without verifying the signature.
274 275 276 |
# File 'lib/jose/jwt.rb', line 274 def self.peek_protected(signed) return JOSE::JWS.peek_protected(signed) end |
.peek_signature(signed) ⇒ String
Returns the decoded signature portion of a signed binary or map without verifying the signature.
282 283 284 |
# File 'lib/jose/jwt.rb', line 282 def self.peek_signature(signed) return JOSE::JWS.peek_signature(signed) end |
.sign(jwk, jws, jwt = nil, header = nil) ⇒ JOSE::SignedMap
Signs a JOSE::JWT using the jwk
and the default signer algorithm jws
for the key type.
294 295 296 297 298 299 300 |
# File 'lib/jose/jwt.rb', line 294 def self.sign(jwk, jws, jwt = nil, header = nil) if jwt.nil? jwt = jws jws = nil end return from(jwt).sign(jwk, jws, header) end |
.to_binary(jwt) ⇒ String+
Converts a JOSE::JWT into a binary.
138 139 140 141 142 143 144 |
# File 'lib/jose/jwt.rb', line 138 def self.to_binary(jwt) if jwt.is_a?(Array) return from(jwt).map { |obj| obj.to_binary } else return from(jwt).to_binary end end |
.to_file(jwt, file) ⇒ Fixnum
156 157 158 |
# File 'lib/jose/jwt.rb', line 156 def self.to_file(jwt, file) return from(jwt).to_file(file) end |
.to_map(jwt) ⇒ JOSE::Map+
Converts a JOSE::JWT into a map.
170 171 172 173 174 175 176 |
# File 'lib/jose/jwt.rb', line 170 def self.to_map(jwt) if jwt.is_a?(Array) return from(jwt).map { |obj| obj.to_map } else return from(jwt).to_map end end |
.verify(jwk, signed) ⇒ [Boolean, JOSE::JWT, JOSE::JWS]
Verifies the signed
using the jwk
and calls JOST::JWT.from on the payload.
327 328 329 330 331 |
# File 'lib/jose/jwt.rb', line 327 def self.verify(jwk, signed) verified, payload, jws = JOSE::JWK.verify(signed, jwk) jwt = from_binary(payload) return verified, jwt, jws end |
.verify_strict(jwk, allow, signed) ⇒ [Boolean, (JOSE::JWT, String), (JOSE::JWS, JOSE::Map)]
Verifies the signed
using the jwk
, whitelists the "alg"
using allow
, and calls JOST::JWT.from on the payload.
339 340 341 342 343 344 345 346 |
# File 'lib/jose/jwt.rb', line 339 def self.verify_strict(jwk, allow, signed) verified, payload, jws = JOSE::JWK.verify_strict(signed, allow, jwk) jwt = payload if verified jwt = from_binary(payload) end return verified, jwt, jws end |
Instance Method Details
#encrypt(jwk, jwe = nil) ⇒ JOSE::EncryptedMap
Encrypts a JOSE::JWT using the jwk
and the jwe
algorithm.
If "typ"
is not specified in the jwe
, { "typ" => "JWT" }
will be added.
217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/jose/jwt.rb', line 217 def encrypt(jwk, jwe = nil) plain_text = to_binary if jwe.nil? jwk = JOSE::JWK.from(jwk) jwe = (jwk.is_a?(Array) ? jwk.last : jwk).block_encryptor end if jwe.is_a?(Hash) jwe = JOSE::Map.new(jwe) end if jwe.is_a?(JOSE::Map) and not jwe.has_key?('typ') jwe = jwe.put('typ', 'JWT') end return JOSE::JWK.block_encrypt(jwk, plain_text, jwe) end |
#merge(object) ⇒ JOSE::JWT
Merges object into current map.
243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/jose/jwt.rb', line 243 def merge(object) object = case object when JOSE::Map, Hash object when String JOSE.decode(object) when JOSE::JWT object.to_map else raise ArgumentError, "'object' must be a Hash, String, or JOSE::JWT" end return JOSE::JWT.from_map(self.to_map.merge(object)) end |
#sign(jwk, jws = nil, header = nil) ⇒ JOSE::SignedMap
Signs a JOSE::JWT using the jwk
and the jws
algorithm.
309 310 311 312 313 314 315 316 317 318 319 320 |
# File 'lib/jose/jwt.rb', line 309 def sign(jwk, jws = nil, header = nil) plain_text = to_binary if jws.nil? jwk = JOSE::JWK.from(jwk) jws = jwk.signer end jws = JOSE::JWS.from(jws).to_map if not jws.has_key?('typ') jws = jws.put('typ', 'JWT') end return JOSE::JWK.sign(plain_text, jws, jwk, header) end |
#to_binary ⇒ String
Converts a JOSE::JWT into a binary.
148 149 150 |
# File 'lib/jose/jwt.rb', line 148 def to_binary return JOSE.encode(to_map) end |
#to_file(file) ⇒ Fixnum
Calls #to_binary on a JOSE::JWT and then writes the binary to file
.
163 164 165 |
# File 'lib/jose/jwt.rb', line 163 def to_file(file) return File.binwrite(file, to_binary) end |