Class: JOSE::JWK
- Inherits:
-
Struct
- Object
- Struct
- JOSE::JWK
- Defined in:
- lib/jose/jwk.rb
Overview
JWK stands for JSON Web Key which is defined in RFC 7517.
Defined Under Namespace
Modules: KTY, OpenSSHKey, PEM Classes: KTY_EC, KTY_OKP_Ed25519, KTY_OKP_Ed25519ph, KTY_OKP_Ed448, KTY_OKP_Ed448ph, KTY_OKP_X25519, KTY_OKP_X448, KTY_RSA, KTY_oct, PKeyProxy, Set
Instance Attribute Summary collapse
-
#fields ⇒ Object
Returns the value of attribute fields.
-
#keys ⇒ Object
Returns the value of attribute keys.
-
#kty ⇒ Object
Returns the value of attribute kty.
Class Method Summary collapse
-
.block_decrypt(jwk, encrypted) ⇒ [String, JOSE::JWE]
Decrypts the
encrypted
binary or map using thejwk
. -
.block_encrypt(jwk, plain_text, jwe = nil) ⇒ JOSE::EncryptedMap
Encrypts the
plain_text
using thejwk
and algorithms specified by thejwe
. -
.block_encryptor(jwk) ⇒ JOSE::Map+
Returns a block encryptor map for the key type.
-
.box_decrypt(jwk, encrypted, public_jwk = nil) ⇒ [String, JOSE::JWE]
Key Agreement decryption of the
encrypted
binary or map usingmy_private_jwk
. -
.box_encrypt(plain_text, box_keys, jwe = nil) ⇒ JOSE::EncryptedMap, [JOSE::EncryptedMap, JOSE::JWK]
Key Agreement encryption of
plain_text
by generating an ephemeral private key based onother_public_jwk
curve. -
.derive_key(jwk, *args) ⇒ String
Derives a key (typically just returns a binary representation of the key).
-
.from(object, modules = nil, key = nil) ⇒ JOSE::JWK+
Converts a binary or map into a
JOSE.JWK
. -
.from_binary(object, modules = nil, key = nil) ⇒ JOSE::JWK+
Converts a binary into a JOSE::JWK.
-
.from_file(file, modules = nil, key = nil) ⇒ JOSE::JWK
Reads file and calls JWK.from_binary to convert into a JOSE::JWK.
-
.from_key(object, modules = {}) ⇒ JOSE::JWK
Converts Ruby records for EC and RSA keys into a JOSE::JWK.
-
.from_map(object, modules = nil, key = nil) ⇒ JOSE::JWK+
Converts a map into a JOSE::JWK.
-
.from_oct(object, modules = {}) ⇒ JOSE::JWK
Converts an arbitrary binary into a JOSE::JWK with
"kty"
of"oct"
. -
.from_oct_file(file, modules = {}) ⇒ JOSE::JWK
Reads file and calls JOSE::JWK.from_oct to convert into a JOSE::JWK.
-
.from_okp(object, modules = {}) ⇒ JOSE::JWK
Converts an octet key pair into a JOSE::JWK with
"kty"
of"OKP"
. -
.from_openssh_key(object, modules = {}) ⇒ JOSE::JWK
Converts an openssh key into a JOSE::JWK with
"kty"
of"OKP"
. -
.from_openssh_key_file(file, modules = {}) ⇒ JOSE::JWK
Reads file and calls JOSE::JWK.from_openssh_key to convert into a JOSE::JWK.
-
.from_pem(object, modules = nil, password = nil) ⇒ JOSE::JWK
Converts a PEM (Privacy Enhanced Email) binary into a JOSE::JWK.
-
.from_pem_file(file, modules = nil, password = nil) ⇒ JOSE::JWK
Reads file and calls JOSE::JWK.from_pem to convert into a JOSE::JWK.
- .generate_key(params) ⇒ JOSE::JWK
-
.merge(left, right) ⇒ JOSE::JWK
Merges map on right into map on left.
-
.shared_secret(your_jwk, my_jwk) ⇒ String
Computes the shared secret between two keys.
-
.sign(plain_text, jws, jwk = nil, header = nil) ⇒ JOSE::SignedMap
Signs the
plain_text
using thejwk
and the default signer algorithmjws
for the key type. -
.signer(jwk) ⇒ JOSE::Map
Returns a signer map for the key type.
-
.thumbprint(digest_type, jwk = nil) ⇒ String
Returns the unique thumbprint for a JOSE::JWK using the
digest_type
. -
.to_binary(jwk, key = nil, jwe = nil) ⇒ String, ...
Converts a JOSE::JWK into a binary.
-
.to_file(jwk, file, key = nil, jwe = nil) ⇒ Fixnum
Calls JOSE::JWK.to_binary on a JOSE::JWK and then writes the binary to
file
. -
.to_key(jwk) ⇒ OpenSSL::PKey, Object
Converts a JOSE::JWK into the raw key format.
-
.to_map(jwk, key = nil, jwe = nil) ⇒ JOSE::Map+
Converts a JOSE::JWK into a map.
-
.to_oct(jwk) ⇒ String+
Converts a JOSE::JWK into a raw binary octet.
-
.to_oct_file(jwk, file) ⇒ Fixnum
Calls JOSE::JWK.to_oct on a JOSE::JWK and then writes the binary to
file
. -
.to_okp(jwk) ⇒ Object+
Converts a JOSE::JWK into an octet key pair.
-
.to_openssh_key(jwk) ⇒ Object+
Converts a JOSE::JWK into an OpenSSH key binary.
-
.to_openssh_key_file(jwk, file) ⇒ Fixnum
Calls JOSE::JWK.to_openssh_key on a JOSE::JWK and then writes the binary to
file
. -
.to_pem(jwk, password = nil) ⇒ String+
Converts a JOSE::JWK into a PEM (Privacy Enhanced Email) binary.
-
.to_pem_file(jwk, file, password = nil) ⇒ Fixnum
Calls JOSE::JWK.to_pem on a JOSE::JWK and then writes the binary to
file
. - .to_public(jwk) ⇒ JOSE::JWK+
-
.to_public_file(jwk, file) ⇒ Fixnum
Calls JOSE::JWK.to_binary on a JOSE::JWK and then writes the binary to
file
. -
.to_public_key(jwk) ⇒ OpenSSL::PKey, ...
Calls JOSE::JWK.to_public and then JOSE::JWK.to_key on a JOSE::JWK.
-
.to_public_map(jwk) ⇒ JOSE::Map+
Calls JOSE::JWK.to_public and then JOSE::JWK.to_map on a JOSE::JWK.
-
.to_thumbprint_map(jwk) ⇒ JOSE::Map+
Converts a JOSE::JWK into a map that can be used by JOSE::JWK.thumbprint.
-
.verifier(jwk) ⇒ Array<String>
Returns a verifier algorithm list for the key type.
-
.verify(signed, jwk) ⇒ [Boolean, String, JOSE::JWS]
Verifies the
signed
using thejwk
. -
.verify_strict(signed, allow, jwk) ⇒ [Boolean, String, JOSE::JWS]
Verifies the
signed
using thejwk
and whitelists the"alg"
usingallow
.
Instance Method Summary collapse
-
#block_decrypt(encrypted) ⇒ [String, JOSE::JWE]
Decrypts the
encrypted
binary or map using thejwk
. -
#block_encrypt(plain_text, jwe = nil) ⇒ JOSE::EncryptedMap
Encrypts the
plain_text
using thejwk
and algorithms specified by thejwe
. -
#block_encryptor ⇒ JOSE::Map
Returns a block encryptor map for the key type.
-
#box_decrypt(encrypted, public_jwk = nil) ⇒ [String, JOSE::JWE]
Key Agreement decryption of the
encrypted
binary or map usingmy_private_jwk
. -
#box_encrypt(plain_text, jwk_secret = nil, jwe = nil) ⇒ JOSE::EncryptedMap, [JOSE::EncryptedMap, JOSE::JWK]
Key Agreement encryption of
plain_text
by generating an ephemeral private key based onother_public_jwk
curve. -
#derive_key(*args) ⇒ String
Derives a key (typically just returns a binary representation of the key).
-
#generate_key ⇒ JOSE::JWK
Generates a new key based on the current one.
-
#merge(object) ⇒ JOSE::JWK
Merges object into current map.
-
#shared_secret(other_jwk) ⇒ String
Computes the shared secret between two keys.
-
#sign(plain_text, jws = nil, header = nil) ⇒ JOSE::SignedMap
Signs the
plain_text
using thejwk
and the default signer algorithmjws
for the key type. -
#signer ⇒ JOSE::Map
Returns a signer map for the key type.
-
#thumbprint(digest_type = nil) ⇒ String
Returns the unique thumbprint for a JOSE::JWK using the
digest_type
. -
#to_binary(key = nil, jwe = nil) ⇒ String, JOSE::EncryptedBinary
Converts a JOSE::JWK into a binary.
-
#to_file(file, key = nil, jwe = nil) ⇒ Fixnum
Calls JOSE::JWK.to_binary on a JOSE::JWK and then writes the binary to
file
. -
#to_key ⇒ OpenSSL::PKey, Object
Converts a JOSE::JWK into the raw key format.
-
#to_map(key = nil, jwe = nil) ⇒ JOSE::Map
Converts a JOSE::JWK into a map.
-
#to_oct ⇒ String
Converts a JOSE::JWK into a raw binary octet.
-
#to_oct_file(file) ⇒ Fixnum
Calls JOSE::JWK#to_oct on a JOSE::JWK and then writes the binary to
file
. -
#to_okp ⇒ String
Converts a JOSE::JWK into an octet key pair.
-
#to_openssh_key ⇒ Object
Converts a JOSE::JWK into an OpenSSH key binary.
-
#to_openssh_key_file(file) ⇒ Fixnum
Calls JOSE::JWK#to_openssh_key on a JOSE::JWK and then writes the binary to
file
. -
#to_pem(password = nil) ⇒ String
Converts a JOSE::JWK into a PEM (Privacy Enhanced Email) binary.
-
#to_pem_file(file, password = nil) ⇒ Fixnum
Calls JOSE::JWK#to_pem on a JOSE::JWK and then writes the binary to
file
. - #to_public ⇒ JOSE::JWK
-
#to_public_file(file) ⇒ Fixnum
Calls JOSE::JWK.to_public on a JOSE::JWK and then writes the binary to
file
. -
#to_public_key ⇒ OpenSSL::PKey, Object
Calls JOSE::JWK#to_public and then JOSE::JWK#to_key on a JOSE::JWK.
-
#to_public_map ⇒ JOSE::Map
Calls JOSE::JWK#to_public and then JOSE::JWK#to_map on a JOSE::JWK.
-
#to_thumbprint_map ⇒ JOSE::Map
Converts a JOSE::JWK into a map that can be used by JOSE::JWK.thumbprint.
-
#verifier ⇒ Array<String>
Returns a verifier algorithm list for the key type.
-
#verify(signed) ⇒ [Boolean, String, JOSE::JWS]
Verifies the
signed
using thejwk
. -
#verify_strict(signed, allow) ⇒ [Boolean, String, JOSE::JWS]
Verifies the
signed
using thejwk
and whitelists the"alg"
usingallow
.
Instance Attribute Details
#fields ⇒ Object
Returns the value of attribute fields
3 4 5 |
# File 'lib/jose/jwk.rb', line 3 def fields @fields end |
#keys ⇒ Object
Returns the value of attribute keys
3 4 5 |
# File 'lib/jose/jwk.rb', line 3 def keys @keys end |
#kty ⇒ Object
Returns the value of attribute kty
3 4 5 |
# File 'lib/jose/jwk.rb', line 3 def kty @kty end |
Class Method Details
.block_decrypt(jwk, encrypted) ⇒ [String, JOSE::JWE]
Decrypts the encrypted
binary or map using the jwk
.
601 602 603 604 605 606 607 608 609 610 611 612 |
# File 'lib/jose/jwk.rb', line 601 def self.block_decrypt(jwk, encrypted) if jwk.is_a?(Array) public_jwk, secret_jwk = from(jwk) if secret_jwk.nil? secret_jwk = public_jwk public_jwk = nil end return box_decrypt(secret_jwk, encrypted, public_jwk) else return from(jwk).block_decrypt(encrypted) end end |
.block_encrypt(jwk, plain_text, jwe = nil) ⇒ JOSE::EncryptedMap
Encrypts the plain_text
using the jwk
and algorithms specified by the jwe
.
630 631 632 633 634 635 636 |
# File 'lib/jose/jwk.rb', line 630 def self.block_encrypt(jwk, plain_text, jwe = nil) if jwk.is_a?(Array) return box_encrypt(plain_text, from(jwk), jwe) else return from(jwk).block_encrypt(plain_text, jwe) end end |
.block_encryptor(jwk) ⇒ JOSE::Map+
Returns a block encryptor map for the key type.
653 654 655 656 657 658 659 |
# File 'lib/jose/jwk.rb', line 653 def self.block_encryptor(jwk) if jwk.is_a?(Array) return from(jwk).map { |obj| obj.block_encryptor } else return from(jwk).block_encryptor end end |
.box_decrypt(jwk, encrypted, public_jwk = nil) ⇒ [String, JOSE::JWE]
Key Agreement decryption of the encrypted
binary or map using my_private_jwk
.
676 677 678 |
# File 'lib/jose/jwk.rb', line 676 def self.box_decrypt(jwk, encrypted, public_jwk = nil) return from(jwk).box_decrypt(encrypted, public_jwk) end |
.box_encrypt(plain_text, box_keys, jwe = nil) ⇒ JOSE::EncryptedMap, [JOSE::EncryptedMap, JOSE::JWK]
Key Agreement encryption of plain_text
by generating an ephemeral private key based on other_public_jwk
curve.
If no private key has been specified in box_keys
, it generates an ephemeral private key based on other public key curve.
705 706 707 708 |
# File 'lib/jose/jwk.rb', line 705 def self.box_encrypt(plain_text, box_keys, jwe = nil) jwk_public, jwk_secret = from(box_keys) return jwk_public.box_encrypt(plain_text, jwk_secret, jwe) end |
.derive_key(jwk, *args) ⇒ String
Derives a key (typically just returns a binary representation of the key).
758 759 760 |
# File 'lib/jose/jwk.rb', line 758 def self.derive_key(jwk, *args) return from(jwk).derive_key(*args) end |
.from(object, modules = nil, key = nil) ⇒ JOSE::JWK+
Converts a binary or map into a JOSE.JWK
.
JOSE::JWK.from({"k" => "", "kty" => "oct"})
# => #<struct JOSE::JWK keys=nil, kty=#<struct JOSE::JWK::KTY_oct oct="">, fields=JOSE::Map[]>
JOSE::JWK.from("{\"k\":\"\",\"kty\":\"oct\"}")
# => #<struct JOSE::JWK keys=nil, kty=#<struct JOSE::JWK::KTY_oct oct="">, fields=JOSE::Map[]>
The "kty"
field may be overridden with a custom module that implements the JOSE::JWK::KTY behaviours.
For example:
JOSE::JWK.from({ "kty" => "custom" }, { kty: MyCustomKey })
# => #<struct JOSE::JWK keys=nil, kty=#<MyCustomKey:0x007f8c5419ff68>, fields=JOSE::Map[]>
If a key
has been specified, it will decrypt an encrypted binary or map into a JOSE::JWK using the specified key
.
JOSE::JWK.from("eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkExMjhHQ00iLCJwMmMiOjQwOTYsInAycyI6Im5OQ1ZNQUktNTU5UVFtbWRFcnBsZFEifQ.Ucye69ii4dxd1ykNFlJyBVeA6xeNu4aV.2pZ4nBoxBjmdrneS.boqwdFZVNAFHk1M5P6kPYgBUgGwW32QuKzHuFA.wL9Hy6dcE_DPkUW9s5iwKA", "password")
# => [#<struct JOSE::JWK keys=nil, kty=#<struct JOSE::JWK::KTY_oct oct="secret">, fields=JOSE::Map[]>,
# #<struct JOSE::JWE
# alg=
# #<struct JOSE::JWE::ALG_PBES2
# hmac=OpenSSL::Digest::SHA256,
# bits=128,
# salt="PBES2-HS256+A128KW\x00\x9C\xD0\x950\x02>\xE7\x9FPBi\x9D\x12\xBAeu",
# iter=4096>,
# 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["cty" => "jwk+json"]>]
43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/jose/jwk.rb', line 43 def self.from(object, modules = nil, key = nil) case object when JOSE::Map, Hash return from_map(object, modules, key) when String return from_binary(object, modules, key) when JOSE::JWK return object when Array return object.map { |obj| from(obj, modules, key) } else raise ArgumentError, "'object' must be a Hash, String, JOSE::JWK, or Array" end end |
.from_binary(object, modules = nil, key = nil) ⇒ JOSE::JWK+
Converts a binary into a JOSE::JWK.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/jose/jwk.rb', line 64 def self.from_binary(object, modules = nil, key = nil) if (modules.is_a?(String) or modules.is_a?(JOSE::JWK)) and key.nil? key = modules modules = {} end modules ||= {} case object when String if key plain_text, jwe = JOSE::JWE.block_decrypt(key, object) return from_binary(plain_text, modules), jwe else return from_map(JOSE.decode(object), modules) end when Array return object.map { |obj| from_binary(obj, modules, key) } else raise ArgumentError, "'object' must be a String or Array" end end |
.from_file(file, modules = nil, key = nil) ⇒ JOSE::JWK
Reads file and calls from_binary to convert into a JOSE::JWK.
91 92 93 |
# File 'lib/jose/jwk.rb', line 91 def self.from_file(file, modules = nil, key = nil) return from_binary(File.binread(file), modules, key) end |
.from_key(object, modules = {}) ⇒ JOSE::JWK
Converts Ruby records for EC and RSA keys into a JOSE::JWK.
100 101 102 103 |
# File 'lib/jose/jwk.rb', line 100 def self.from_key(object, modules = {}) kty = modules[:kty] || JOSE::JWK::KTY return JOSE::JWK.new(nil, *kty.from_key(object)) end |
.from_map(object, modules = nil, key = nil) ⇒ JOSE::JWK+
Converts a map into a JOSE::JWK.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/jose/jwk.rb', line 111 def self.from_map(object, modules = nil, key = nil) if (modules.is_a?(String) or modules.is_a?(JOSE::JWK)) and key.nil? key = modules modules = {} end modules ||= {} case object when JOSE::Map, Hash if key plain_text, jwe = JOSE::JWE.block_decrypt(key, object) return from_binary(plain_text, modules), jwe else return from_fields(JOSE::JWK.new(nil, nil, JOSE::Map.new(object)), modules) end when Array return object.map { |obj| from_map(obj, modules, key) } else raise ArgumentError, "'object' must be a JOSE::Map, Hash, or Array" end end |
.from_oct(object, modules = {}) ⇒ JOSE::JWK
Converts an arbitrary binary into a JOSE::JWK with "kty"
of "oct"
.
137 138 139 140 |
# File 'lib/jose/jwk.rb', line 137 def self.from_oct(object, modules = {}) kty = modules[:kty] || JOSE::JWK::KTY_oct return JOSE::JWK.new(nil, *kty.from_oct(object)) end |
.from_oct_file(file, modules = {}) ⇒ JOSE::JWK
Reads file and calls JOSE::JWK.from_oct to convert into a JOSE::JWK.
147 148 149 |
# File 'lib/jose/jwk.rb', line 147 def self.from_oct_file(file, modules = {}) return from_oct(File.binread(file), modules) end |
.from_okp(object, modules = {}) ⇒ JOSE::JWK
Converts an octet key pair into a JOSE::JWK with "kty"
of "OKP"
.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/jose/jwk.rb', line 156 def self.from_okp(object, modules = {}) raise ArgumentError, "object must be an Array of length 2" if not object.is_a?(Array) or object.length != 2 kty = modules[:kty] || case object[0] when :Ed25519 JOSE::JWK::KTY_OKP_Ed25519 when :Ed25519ph JOSE::JWK::KTY_OKP_Ed25519ph when :Ed448 JOSE::JWK::KTY_OKP_Ed448 when :Ed448ph JOSE::JWK::KTY_OKP_Ed448ph when :X25519 JOSE::JWK::KTY_OKP_X25519 when :X448 JOSE::JWK::KTY_OKP_X448 else raise ArgumentError, "unrecognized :okp object" end return JOSE::JWK.new(nil, *kty.from_okp(object)) end |
.from_openssh_key(object, modules = {}) ⇒ JOSE::JWK
Converts an openssh key into a JOSE::JWK with "kty"
of "OKP"
.
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/jose/jwk.rb', line 182 def self.from_openssh_key(object, modules = {}) raise ArgumentError, "object must be a String or Array" if not object.is_a?(String) and not object.is_a?(Array) keys = object if object.is_a?(String) keys = JOSE::JWK::OpenSSHKey.from_binary(object) end ((pk_type, pk), key), = keys[0] sk_type, sk_pk, = key if pk_type and pk and key and sk_type and sk_pk and pk_type == sk_type and pk == sk_pk kty = modules[:kty] || case pk_type when 'ssh-ed25519' JOSE::JWK::KTY_OKP_Ed25519 when 'ssh-ed25519ph' JOSE::JWK::KTY_OKP_Ed25519ph when 'ssh-ed448' JOSE::JWK::KTY_OKP_Ed448 when 'ssh-ed448ph' JOSE::JWK::KTY_OKP_Ed448ph when 'ssh-x25519' JOSE::JWK::KTY_OKP_X25519 when 'ssh-x448' JOSE::JWK::KTY_OKP_X448 else raise ArgumentError, "unrecognized openssh key type: #{pk_type.inspect}" end return JOSE::JWK.new(nil, *kty.from_openssh_key(key)) else raise ArgumentError, "unrecognized openssh key format" end end |
.from_openssh_key_file(file, modules = {}) ⇒ JOSE::JWK
Reads file and calls JOSE::JWK.from_openssh_key to convert into a JOSE::JWK.
218 219 220 |
# File 'lib/jose/jwk.rb', line 218 def self.from_openssh_key_file(file, modules = {}) return from_openssh_key(File.binread(file), modules) end |
.from_pem(object, modules = nil, password = nil) ⇒ JOSE::JWK
230 231 232 233 234 235 236 237 238 |
# File 'lib/jose/jwk.rb', line 230 def self.from_pem(object, modules = nil, password = nil) if modules.is_a?(String) and password.nil? password = modules modules = {} end modules ||= {} kty = modules[:kty] || JOSE::JWK::PEM return JOSE::JWK.new(nil, *kty.from_binary(object, password)) end |
.from_pem_file(file, modules = nil, password = nil) ⇒ JOSE::JWK
Reads file and calls JOSE::JWK.from_pem to convert into a JOSE::JWK.
246 247 248 |
# File 'lib/jose/jwk.rb', line 246 def self.from_pem_file(file, modules = nil, password = nil) return from_pem(File.binread(file), modules, password) end |
.generate_key(params) ⇒ JOSE::JWK
Generates a new JOSE::JWK based on another JOSE::JWK or from initialization params provided.
Passing another JOSE::JWK results in different behavior depending on the "kty"
:
"EC"
- uses the same named curve to generate a new key"oct"
- uses the byte size to generate a new key"OKP"
- uses the named curve to generate a new key"RSA"
- uses the same modulus and exponent sizes to generate a new key
The following initialization params may also be used:
[:ec, "P-256" | "P-384" | "P-521"]
- generates an"EC"
key using the"P-256"
,"P-384"
, or"P-521"
curves[:oct, bytes]
- generates an"oct"
key made of a randombytes
number of bytes[:okp, :Ed25519 | :Ed25519ph | :Ed448 | :Ed448ph | :X25519 | :X448]
- generates an"OKP"
key using the specified curve[:rsa, modulus_size] | [:rsa, modulus_size, exponent_size]
- generates an"RSA"
key using themodulus_size
andexponent_size
788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 |
# File 'lib/jose/jwk.rb', line 788 def self.generate_key(params) if params.is_a?(Array) and (params.length == 2 or params.length == 3) case params[0] when :ec return JOSE::JWK.new(nil, *JOSE::JWK::KTY_EC.generate_key(params)) when :oct return JOSE::JWK.new(nil, *JOSE::JWK::KTY_oct.generate_key(params)) when :okp case params[1] when :Ed25519 return JOSE::JWK.new(nil, *JOSE::JWK::KTY_OKP_Ed25519.generate_key(params)) when :Ed25519ph return JOSE::JWK.new(nil, *JOSE::JWK::KTY_OKP_Ed25519ph.generate_key(params)) when :Ed448 return JOSE::JWK.new(nil, *JOSE::JWK::KTY_OKP_Ed448.generate_key(params)) when :Ed448ph return JOSE::JWK.new(nil, *JOSE::JWK::KTY_OKP_Ed448ph.generate_key(params)) when :X25519 return JOSE::JWK.new(nil, *JOSE::JWK::KTY_OKP_X25519.generate_key(params)) when :X448 return JOSE::JWK.new(nil, *JOSE::JWK::KTY_OKP_X448.generate_key(params)) else raise ArgumentError, "invalid :okp key generation params" end when :rsa return JOSE::JWK.new(nil, *JOSE::JWK::KTY_RSA.generate_key(params)) else raise ArgumentError, "invalid key generation params" end elsif params.is_a?(JOSE::JWK) return params.generate_key elsif params.respond_to?(:generate_key) return JOSE::JWK.new(nil, *params.generate_key(JOSE::Map[])) else raise ArgumentError, "invalid key generation params" end end |
.merge(left, right) ⇒ JOSE::JWK
Merges map on right into map on left.
837 838 839 |
# File 'lib/jose/jwk.rb', line 837 def self.merge(left, right) return from(left).merge(right) end |
.shared_secret(your_jwk, my_jwk) ⇒ String
Computes the shared secret between two keys.
Currently only works for "EC"
keys and "OKP"
keys with "crv"
set to "X25519"
or "X448"
.
865 866 867 |
# File 'lib/jose/jwk.rb', line 865 def self.shared_secret(your_jwk, my_jwk) return from(your_jwk).shared_secret(from(my_jwk)) end |
.sign(plain_text, jws, jwk = nil, header = nil) ⇒ JOSE::SignedMap
Signs the plain_text
using the jwk
and the default signer algorithm jws
for the key type.
890 891 892 893 894 895 896 |
# File 'lib/jose/jwk.rb', line 890 def self.sign(plain_text, jws, jwk = nil, header = nil) if jwk.nil? jwk = jws jws = nil end return from(jwk).sign(plain_text, jws, header) end |
.signer(jwk) ⇒ JOSE::Map
Returns a signer map for the key type.
914 915 916 |
# File 'lib/jose/jwk.rb', line 914 def self.signer(jwk) return from(jwk).signer end |
.thumbprint(digest_type, jwk = nil) ⇒ String
Returns the unique thumbprint for a JOSE::JWK using the digest_type
.
# let's define two different keys that will have the same thumbprint
jwk1 = JOSE::JWK.from_oct("secret")
jwk2 = JOSE::JWK.from({ "use" => "sig", "k" => "c2VjcmV0", "kty" => "oct" })
JOSE::JWK.thumbprint(jwk1)
# => "DWBh0SEIAPYh1x5uvot4z3AhaikHkxNJa3Ada2fT-Cg"
JOSE::JWK.thumbprint(jwk2)
# => "DWBh0SEIAPYh1x5uvot4z3AhaikHkxNJa3Ada2fT-Cg"
JOSE::JWK.thumbprint('MD5', jwk1)
# => "Kldz8k5PQm7y1E3aNBlMiA"
JOSE::JWK.thumbprint('MD5', jwk2)
# => "Kldz8k5PQm7y1E3aNBlMiA"
945 946 947 948 949 950 951 |
# File 'lib/jose/jwk.rb', line 945 def self.thumbprint(digest_type, jwk = nil) if jwk.nil? jwk = digest_type digest_type = nil end return from(jwk).thumbprint(digest_type) end |
.to_binary(jwk, key = nil, jwe = nil) ⇒ String, ...
Converts a JOSE::JWK into a binary.
258 259 260 261 262 263 264 |
# File 'lib/jose/jwk.rb', line 258 def self.to_binary(jwk, key = nil, jwe = nil) if jwk.is_a?(Array) return jwk.map { |obj| from(obj).to_binary(key, jwe) } else return from(jwk).to_binary(key, jwe) end end |
.to_file(jwk, file, key = nil, jwe = nil) ⇒ Fixnum
Calls JOSE::JWK.to_binary on a JOSE::JWK and then writes the binary to file
.
289 290 291 |
# File 'lib/jose/jwk.rb', line 289 def self.to_file(jwk, file, key = nil, jwe = nil) return from(jwk).to_file(file, key, jwe) end |
.to_key(jwk) ⇒ OpenSSL::PKey, Object
Converts a JOSE::JWK into the raw key format.
307 308 309 |
# File 'lib/jose/jwk.rb', line 307 def self.to_key(jwk) return from(jwk).to_key end |
.to_map(jwk, key = nil, jwe = nil) ⇒ JOSE::Map+
Converts a JOSE::JWK into a map.
324 325 326 327 328 329 330 |
# File 'lib/jose/jwk.rb', line 324 def self.to_map(jwk, key = nil, jwe = nil) if jwk.is_a?(Array) return from(jwk).map { |obj| obj.to_map(key, jwe) } else return from(jwk).to_map(key, jwe) end end |
.to_oct(jwk) ⇒ String+
Converts a JOSE::JWK into a raw binary octet.
354 355 356 357 358 359 360 |
# File 'lib/jose/jwk.rb', line 354 def self.to_oct(jwk) if jwk.is_a?(Array) return from(jwk).map { |obj| obj.to_oct } else return from(jwk).to_oct end end |
.to_oct_file(jwk, file) ⇒ Fixnum
Calls JOSE::JWK.to_oct on a JOSE::JWK and then writes the binary to file
.
374 375 376 |
# File 'lib/jose/jwk.rb', line 374 def self.to_oct_file(jwk, file) return from(jwk).to_oct_file(file) end |
.to_okp(jwk) ⇒ Object+
Converts a JOSE::JWK into an octet key pair.
390 391 392 393 394 395 396 |
# File 'lib/jose/jwk.rb', line 390 def self.to_okp(jwk) if jwk.is_a?(Array) return from(jwk).map { |obj| obj.to_okp } else return from(jwk).to_okp end end |
.to_openssh_key(jwk) ⇒ Object+
Converts a JOSE::JWK into an OpenSSH key binary.
409 410 411 412 413 414 415 |
# File 'lib/jose/jwk.rb', line 409 def self.to_openssh_key(jwk) if jwk.is_a?(Array) return from(jwk).map { |obj| obj.to_openssh_key } else return from(jwk).to_openssh_key end end |
.to_openssh_key_file(jwk, file) ⇒ Fixnum
Calls JOSE::JWK.to_openssh_key on a JOSE::JWK and then writes the binary to file
.
429 430 431 |
# File 'lib/jose/jwk.rb', line 429 def self.to_openssh_key_file(jwk, file) return from(jwk).to_openssh_key_file(file) end |
.to_pem(jwk, password = nil) ⇒ String+
Converts a JOSE::JWK into a PEM (Privacy Enhanced Email) binary.
446 447 448 449 450 451 452 |
# File 'lib/jose/jwk.rb', line 446 def self.to_pem(jwk, password = nil) if jwk.is_a?(Array) return from(jwk).map { |obj| obj.to_pem(password) } else return from(jwk).to_pem(password) end end |
.to_pem_file(jwk, file, password = nil) ⇒ Fixnum
Calls JOSE::JWK.to_pem on a JOSE::JWK and then writes the binary to file
.
468 469 470 |
# File 'lib/jose/jwk.rb', line 468 def self.to_pem_file(jwk, file, password = nil) return from(jwk).to_pem_file(file, password) end |
.to_public(jwk) ⇒ JOSE::JWK+
Converts a private JOSE::JWK into a public JOSE::JWK.
jwk_rsa = JOSE::JWK.generate_key([:rsa, 1024]).to_map
# => JOSE::Map[
# "dq" => "Iv_BghpjRyv8hk4AgsX_3w",
# "e" => "AQAB",
# "d" => "imiCh2gK77pDAa_NuQbHN1hZdLY0eTl8tp4WLfe1uQ0",
# "p" => "-eKE_wk7O5JWw_1fw-rciw",
# "qi" => "MqCwIoTTCkYmGQHsOM7IuA",
# "n" => "vj2WbxlGF1yU9SoQJMqKw6c2asTks_cVuXEAO3x_yOU",
# "kty" => "RSA",
# "q" => "wuVog_0-60w7_56y8wZuTw",
# "dp" => "lU_9GEdz1UzD-6hSqMaVsQ"]
JOSE::JWK.to_public(jwk_rsa).to_map
# => JOSE::Map[
# "e" => "AQAB",
# "n" => "vj2WbxlGF1yU9SoQJMqKw6c2asTks_cVuXEAO3x_yOU",
# "kty" => "RSA"]
503 504 505 506 507 508 509 |
# File 'lib/jose/jwk.rb', line 503 def self.to_public(jwk) if jwk.is_a?(Array) return from(jwk).map { |obj| obj.to_public } else return from(jwk).to_public end end |
.to_public_file(jwk, file) ⇒ Fixnum
Calls JOSE::JWK.to_binary on a JOSE::JWK and then writes the binary to file
.
524 525 526 |
# File 'lib/jose/jwk.rb', line 524 def self.to_public_file(jwk, file) return from(jwk).to_public_file(file) end |
.to_public_key(jwk) ⇒ OpenSSL::PKey, ...
Calls JOSE::JWK.to_public and then JOSE::JWK.to_key on a JOSE::JWK.
540 541 542 543 544 545 546 |
# File 'lib/jose/jwk.rb', line 540 def self.to_public_key(jwk) if jwk.is_a?(Array) return from(jwk).map { |obj| obj.to_public_key } else return from(jwk).to_public_key end end |
.to_public_map(jwk) ⇒ JOSE::Map+
Calls JOSE::JWK.to_public and then JOSE::JWK.to_map on a JOSE::JWK.
559 560 561 562 563 564 565 |
# File 'lib/jose/jwk.rb', line 559 def self.to_public_map(jwk) if jwk.is_a?(Array) return from(jwk).map { |obj| obj.to_public_map } else return from(jwk).to_public_map end end |
.to_thumbprint_map(jwk) ⇒ JOSE::Map+
Converts a JOSE::JWK into a map that can be used by JOSE::JWK.thumbprint.
578 579 580 581 582 583 584 |
# File 'lib/jose/jwk.rb', line 578 def self.to_thumbprint_map(jwk) if jwk.is_a?(Array) return from(jwk).map { |obj| obj.to_thumbprint_map } else return from(jwk).to_thumbprint_map end end |
.verifier(jwk) ⇒ Array<String>
Returns a verifier algorithm list for the key type.
969 970 971 972 973 974 975 |
# File 'lib/jose/jwk.rb', line 969 def self.verifier(jwk) if jwk.is_a?(Array) return from(jwk).map { |obj| obj.verifier } else return from(jwk).verifier end end |
.verify(signed, jwk) ⇒ [Boolean, String, JOSE::JWS]
Verifies the signed
using the jwk
.
990 991 992 |
# File 'lib/jose/jwk.rb', line 990 def self.verify(signed, jwk) return from(jwk).verify(signed) end |
.verify_strict(signed, allow, jwk) ⇒ [Boolean, String, JOSE::JWS]
Verifies the signed
using the jwk
and whitelists the "alg"
using allow
.
1010 1011 1012 |
# File 'lib/jose/jwk.rb', line 1010 def self.verify_strict(signed, allow, jwk) return from(jwk).verify_strict(signed, allow) end |
Instance Method Details
#block_decrypt(encrypted) ⇒ [String, JOSE::JWE]
Decrypts the encrypted
binary or map using the jwk
.
619 620 621 |
# File 'lib/jose/jwk.rb', line 619 def block_decrypt(encrypted) return JOSE::JWE.block_decrypt(self, encrypted) end |
#block_encrypt(plain_text, jwe = nil) ⇒ JOSE::EncryptedMap
Encrypts the plain_text
using the jwk
and algorithms specified by the jwe
.
644 645 646 647 |
# File 'lib/jose/jwk.rb', line 644 def block_encrypt(plain_text, jwe = nil) jwe ||= block_encryptor return JOSE::JWE.block_encrypt(self, plain_text, jwe) end |
#block_encryptor ⇒ JOSE::Map
Returns a block encryptor map for the key type.
664 665 666 |
# File 'lib/jose/jwk.rb', line 664 def block_encryptor return kty.block_encryptor(fields) end |
#box_decrypt(encrypted, public_jwk = nil) ⇒ [String, JOSE::JWE]
Key Agreement decryption of the encrypted
binary or map using my_private_jwk
.
687 688 689 690 691 692 693 |
# File 'lib/jose/jwk.rb', line 687 def box_decrypt(encrypted, public_jwk = nil) if public_jwk return JOSE::JWE.block_decrypt([public_jwk, self], encrypted) else return JOSE::JWE.block_decrypt(self, encrypted) end end |
#box_encrypt(plain_text, jwk_secret = nil, jwe = nil) ⇒ JOSE::EncryptedMap, [JOSE::EncryptedMap, JOSE::JWK]
Key Agreement encryption of plain_text
by generating an ephemeral private key based on other_public_jwk
curve.
If no private key has been specified in my_private_key
, it generates an ephemeral private key based on other public key curve.
720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 |
# File 'lib/jose/jwk.rb', line 720 def box_encrypt(plain_text, jwk_secret = nil, jwe = nil) epk_secret = nil jwk_public = self if jwk_secret.nil? epk_secret = jwk_secret = jwk_public.generate_key end if not jwk_secret.is_a?(JOSE::JWK) jwk_secret = JOSE::JWK.from(jwk_secret) end if jwe.nil? jwe = jwk_public.block_encryptor end if jwe.is_a?(Hash) jwe = JOSE::Map.new(jwe) end if jwe.is_a?(JOSE::Map) if jwe['apu'].nil? jwe = jwe.put('apu', jwk_secret.fields['kid'] || jwk_secret.thumbprint) end if jwe['apv'].nil? jwe = jwe.put('apv', jwk_public.fields['kid'] || jwk_public.thumbprint) end if jwe['epk'].nil? jwe = jwe.put('epk', jwk_secret.to_public_map) end end if epk_secret return JOSE::JWE.block_encrypt([jwk_public, jwk_secret], plain_text, jwe), epk_secret else return JOSE::JWE.block_encrypt([jwk_public, jwk_secret], plain_text, jwe) end end |
#derive_key(*args) ⇒ String
Derives a key (typically just returns a binary representation of the key).
766 767 768 |
# File 'lib/jose/jwk.rb', line 766 def derive_key(*args) return kty.derive_key(*args) end |
#generate_key ⇒ JOSE::JWK
Generates a new key based on the current one.
829 830 831 |
# File 'lib/jose/jwk.rb', line 829 def generate_key return JOSE::JWK.new(nil, *kty.generate_key(fields)) end |
#merge(object) ⇒ JOSE::JWK
Merges object into current map.
844 845 846 847 848 849 850 851 852 853 854 855 856 |
# File 'lib/jose/jwk.rb', line 844 def merge(object) object = case object when JOSE::Map, Hash object when String JOSE.decode(object) when JOSE::JWK object.to_map else raise ArgumentError, "'object' must be a Hash, String, or JOSE::JWK" end return JOSE::JWK.from_map(self.to_map.merge(object)) end |
#shared_secret(other_jwk) ⇒ String
Computes the shared secret between two keys.
Currently only works for "EC"
keys and "OKP"
keys with "crv"
set to "X25519"
or "X448"
.
875 876 877 878 879 880 |
# File 'lib/jose/jwk.rb', line 875 def shared_secret(other_jwk) other_jwk = from(other_jwk) if not other_jwk.is_a?(JOSE::JWK) raise ArgumentError, "key types must match" if other_jwk.kty.class != kty.class raise ArgumentError, "key type does not support shared secret computations" if not kty.respond_to?(:derive_key) return kty.derive_key(other_jwk) end |
#sign(plain_text, jws = nil, header = nil) ⇒ JOSE::SignedMap
Signs the plain_text
using the jwk
and the default signer algorithm jws
for the key type.
905 906 907 908 |
# File 'lib/jose/jwk.rb', line 905 def sign(plain_text, jws = nil, header = nil) jws ||= signer return JOSE::JWS.sign(self, plain_text, jws, header) end |
#signer ⇒ JOSE::Map
Returns a signer map for the key type.
921 922 923 |
# File 'lib/jose/jwk.rb', line 921 def signer return kty.signer(fields) end |
#thumbprint(digest_type = nil) ⇒ String
Returns the unique thumbprint for a JOSE::JWK using the digest_type
.
959 960 961 962 963 |
# File 'lib/jose/jwk.rb', line 959 def thumbprint(digest_type = nil) digest_type ||= 'SHA256' thumbprint_binary = JOSE.encode(to_thumbprint_map) return JOSE.urlsafe_encode64(OpenSSL::Digest.new(digest_type).digest(thumbprint_binary)) end |
#to_binary(key = nil, jwe = nil) ⇒ String, JOSE::EncryptedBinary
Converts a JOSE::JWK into a binary.
271 272 273 274 275 276 277 278 279 280 |
# File 'lib/jose/jwk.rb', line 271 def to_binary(key = nil, jwe = nil) if not key.nil? jwe ||= kty.key_encryptor(fields, key) end if key and jwe return to_map(key, jwe).compact else return JOSE.encode(to_map) end end |
#to_file(file, key = nil, jwe = nil) ⇒ Fixnum
Calls JOSE::JWK.to_binary on a JOSE::JWK and then writes the binary to file
.
299 300 301 |
# File 'lib/jose/jwk.rb', line 299 def to_file(file, key = nil, jwe = nil) return File.binwrite(file, to_binary(key, jwe)) end |
#to_key ⇒ OpenSSL::PKey, Object
Converts a JOSE::JWK into the raw key format.
314 315 316 |
# File 'lib/jose/jwk.rb', line 314 def to_key return kty.to_key end |
#to_map(key = nil, jwe = nil) ⇒ JOSE::Map
Converts a JOSE::JWK into a map.
337 338 339 340 341 342 343 344 345 346 347 348 |
# File 'lib/jose/jwk.rb', line 337 def to_map(key = nil, jwe = nil) if not key.nil? jwe ||= kty.key_encryptor(fields, key) end if key and jwe return JOSE::JWE.block_encrypt(key, to_binary, jwe) elsif kty.nil? and keys return keys.to_map(fields) else return kty.to_map(fields) end end |
#to_oct ⇒ String
Converts a JOSE::JWK into a raw binary octet.
365 366 367 |
# File 'lib/jose/jwk.rb', line 365 def to_oct return kty.to_oct end |
#to_oct_file(file) ⇒ Fixnum
Calls JOSE::JWK#to_oct on a JOSE::JWK and then writes the binary to file
.
382 383 384 |
# File 'lib/jose/jwk.rb', line 382 def to_oct_file(file) return File.binwrite(file, to_oct) end |
#to_okp ⇒ String
Converts a JOSE::JWK into an octet key pair.
401 402 403 |
# File 'lib/jose/jwk.rb', line 401 def to_okp return kty.to_okp end |
#to_openssh_key ⇒ Object
Converts a JOSE::JWK into an OpenSSH key binary.
420 421 422 |
# File 'lib/jose/jwk.rb', line 420 def to_openssh_key return kty.to_openssh_key(fields) end |
#to_openssh_key_file(file) ⇒ Fixnum
Calls JOSE::JWK#to_openssh_key on a JOSE::JWK and then writes the binary to file
.
437 438 439 |
# File 'lib/jose/jwk.rb', line 437 def to_openssh_key_file(file) return File.binwrite(file, to_openssh_key) end |
#to_pem(password = nil) ⇒ String
Converts a JOSE::JWK into a PEM (Privacy Enhanced Email) binary.
458 459 460 |
# File 'lib/jose/jwk.rb', line 458 def to_pem(password = nil) return kty.to_pem(password) end |
#to_pem_file(file, password = nil) ⇒ Fixnum
Calls JOSE::JWK#to_pem on a JOSE::JWK and then writes the binary to file
.
477 478 479 |
# File 'lib/jose/jwk.rb', line 477 def to_pem_file(file, password = nil) return File.binwrite(file, to_pem(password)) end |
#to_public ⇒ JOSE::JWK
515 516 517 |
# File 'lib/jose/jwk.rb', line 515 def to_public return JOSE::JWK.from_map(to_public_map) end |
#to_public_file(file) ⇒ Fixnum
Calls JOSE::JWK.to_public on a JOSE::JWK and then writes the binary to file
.
532 533 534 |
# File 'lib/jose/jwk.rb', line 532 def to_public_file(file) return File.binwrite(file, to_public.to_binary) end |
#to_public_key ⇒ OpenSSL::PKey, Object
Calls JOSE::JWK#to_public and then JOSE::JWK#to_key on a JOSE::JWK.
551 552 553 |
# File 'lib/jose/jwk.rb', line 551 def to_public_key return to_public.to_key end |
#to_public_map ⇒ JOSE::Map
Calls JOSE::JWK#to_public and then JOSE::JWK#to_map on a JOSE::JWK.
570 571 572 |
# File 'lib/jose/jwk.rb', line 570 def to_public_map return kty.to_public_map(fields) end |
#to_thumbprint_map ⇒ JOSE::Map
Converts a JOSE::JWK into a map that can be used by JOSE::JWK.thumbprint.
589 590 591 |
# File 'lib/jose/jwk.rb', line 589 def to_thumbprint_map return kty.to_thumbprint_map(fields) end |
#verifier ⇒ Array<String>
Returns a verifier algorithm list for the key type.
980 981 982 |
# File 'lib/jose/jwk.rb', line 980 def verifier return kty.verifier(fields) end |
#verify(signed) ⇒ [Boolean, String, JOSE::JWS]
Verifies the signed
using the jwk
.
999 1000 1001 |
# File 'lib/jose/jwk.rb', line 999 def verify(signed) return JOSE::JWS.verify(self, signed) end |
#verify_strict(signed, allow) ⇒ [Boolean, String, JOSE::JWS]
Verifies the signed
using the jwk
and whitelists the "alg"
using allow
.
1020 1021 1022 |
# File 'lib/jose/jwk.rb', line 1020 def verify_strict(signed, allow) return JOSE::JWS.verify_strict(self, allow, signed) end |