Class: JOSE::JWK::KTY_RSA
- Inherits:
-
Struct
- Object
- Struct
- JOSE::JWK::KTY_RSA
- Defined in:
- lib/jose/jwk/kty_rsa.rb
Instance Attribute Summary collapse
-
#key ⇒ Object
Returns the value of attribute key.
Class Method Summary collapse
-
.from_key(key) ⇒ Object
API functions.
-
.from_map(fields) ⇒ Object
JOSE::JWK callbacks.
- .generate_key(modulus_size, exponent_size = nil) ⇒ Object
Instance Method Summary collapse
-
#block_encryptor(fields = nil) ⇒ Object
JOSE::JWK::KTY callbacks.
- #decrypt_private(cipher_text, rsa_padding: :rsa_pkcs1_padding, rsa_oaep_md: nil) ⇒ Object
- #encrypt_public(plain_text, rsa_padding: :rsa_pkcs1_padding, rsa_oaep_md: nil) ⇒ Object
- #generate_key(fields) ⇒ Object
- #key_encryptor(fields, key) ⇒ Object
- #sign(message, digest_type, padding: :rsa_pkcs1_padding) ⇒ Object
- #signer(fields = nil) ⇒ Object
- #to_key ⇒ Object
- #to_map(fields) ⇒ Object
- #to_pem(password = nil) ⇒ Object
- #to_public_map(fields) ⇒ Object
- #to_thumbprint_map(fields) ⇒ Object
- #verifier(fields) ⇒ Object
- #verify(message, digest_type, signature, padding: :rsa_pkcs1_padding) ⇒ Object
Instance Attribute Details
#key ⇒ Object
Returns the value of attribute key
1 2 3 |
# File 'lib/jose/jwk/kty_rsa.rb', line 1 def key @key end |
Class Method Details
.from_key(key) ⇒ Object
API functions
209 210 211 212 213 214 215 216 217 |
# File 'lib/jose/jwk/kty_rsa.rb', line 209 def self.from_key(key) key = key.__getobj__ if key.is_a?(JOSE::JWK::PKeyProxy) case key when OpenSSL::PKey::RSA return JOSE::JWK::KTY_RSA.new(JOSE::JWK::PKeyProxy.new(key)), JOSE::Map[] else raise ArgumentError, "'key' must be a OpenSSL::PKey::RSA" end end |
.from_map(fields) ⇒ Object
JOSE::JWK callbacks
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/jose/jwk/kty_rsa.rb', line 5 def self.from_map(fields) if fields['kty'] == 'RSA' and fields['e'].is_a?(String) and fields['n'].is_a?(String) if fields['oth'].is_a?(Array) raise ArgumentError, "multi-prime RSA keys are not supported" elsif fields['d'].is_a?(String) if fields['dp'].is_a?(String) and fields['dq'].is_a?(String) and fields['p'].is_a?(String) and fields['q'].is_a?(String) and fields['qi'].is_a?(String) asn1_sequence = OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::Integer.new(0), OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['n']), 2)), OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['e']), 2)), OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['d']), 2)), OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['p']), 2)), OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['q']), 2)), OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['dp']), 2)), OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['dq']), 2)), OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['qi']), 2)) ]) rsa = OpenSSL::PKey::RSA.new(asn1_sequence.to_der) return JOSE::JWK::KTY_RSA.new(JOSE::JWK::PKeyProxy.new(rsa)), fields.except('kty', 'd', 'dp', 'dq', 'e', 'n', 'p', 'q', 'qi') else d = OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['d']), 2) e = OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['e']), 2) n = OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['n']), 2) rsa = convert_sfm_to_crt(d, e, n) return JOSE::JWK::KTY_RSA.new(JOSE::JWK::PKeyProxy.new(rsa)), fields.except('kty', 'd', 'dp', 'dq', 'e', 'n', 'p', 'q', 'qi') end else asn1_sequence = OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['n']), 2)), OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['e']), 2)) ]) rsa = OpenSSL::PKey::RSA.new(OpenSSL::PKey::RSA.new(asn1_sequence.to_der)) return JOSE::JWK::KTY_RSA.new(JOSE::JWK::PKeyProxy.new(rsa)), fields.except('kty', 'e', 'n') end else raise ArgumentError, "invalid 'RSA' JWK" end end |
.generate_key(modulus_size, exponent_size = nil) ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/jose/jwk/kty_rsa.rb', line 129 def self.generate_key(modulus_size, exponent_size = nil) if modulus_size.is_a?(Array) if modulus_size.length == 2 and modulus_size[0] == :rsa modulus_size = modulus_size[1] elsif modulus_size.length == 3 and modulus_size[0] == :rsa exponent_size = modulus_size[2] modulus_size = modulus_size[1] end end if modulus_size.is_a?(Integer) and (exponent_size.nil? or exponent_size.is_a?(Integer)) return from_key(OpenSSL::PKey::RSA.generate(modulus_size)) if exponent_size.nil? return from_key(OpenSSL::PKey::RSA.generate(modulus_size, exponent_size)) if exponent_size.is_a?(Integer) else raise ArgumentError, "'modulus_size' must be an Integer and 'exponent_size' must be nil or an Integer" end end |
Instance Method Details
#block_encryptor(fields = nil) ⇒ Object
JOSE::JWK::KTY callbacks
79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/jose/jwk/kty_rsa.rb', line 79 def block_encryptor(fields = nil) if fields and fields['use'] == 'enc' and not fields['alg'].nil? and not fields['enc'].nil? return JOSE::Map[ 'alg' => fields['alg'], 'enc' => fields['enc'] ] else return JOSE::Map[ 'alg' => 'RSA-OAEP', 'enc' => 'A128GCM' ] end end |
#decrypt_private(cipher_text, rsa_padding: :rsa_pkcs1_padding, rsa_oaep_md: nil) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/jose/jwk/kty_rsa.rb', line 93 def decrypt_private(cipher_text, rsa_padding: :rsa_pkcs1_padding, rsa_oaep_md: nil) case rsa_padding when :rsa_pkcs1_padding return key.private_decrypt(cipher_text, OpenSSL::PKey::RSA::PKCS1_PADDING) when :rsa_pkcs1_oaep_padding rsa_oaep_md ||= OpenSSL::Digest::SHA1 if rsa_oaep_md == OpenSSL::Digest::SHA1 return key.private_decrypt(cipher_text, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING) elsif rsa_oaep_md == OpenSSL::Digest::SHA256 return JOSE::JWA::PKCS1.rsaes_oaep_decrypt(rsa_oaep_md, cipher_text, key) else raise ArgumentError, "unsupported RSA OAEP md: #{rsa_oaep_md.inspect}" end else raise ArgumentError, "unsupported RSA padding: #{rsa_padding.inspect}" end end |
#encrypt_public(plain_text, rsa_padding: :rsa_pkcs1_padding, rsa_oaep_md: nil) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/jose/jwk/kty_rsa.rb', line 111 def encrypt_public(plain_text, rsa_padding: :rsa_pkcs1_padding, rsa_oaep_md: nil) case rsa_padding when :rsa_pkcs1_padding return key.public_encrypt(plain_text, OpenSSL::PKey::RSA::PKCS1_PADDING) when :rsa_pkcs1_oaep_padding rsa_oaep_md ||= OpenSSL::Digest::SHA1 if rsa_oaep_md == OpenSSL::Digest::SHA1 return key.public_encrypt(plain_text, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING) elsif rsa_oaep_md == OpenSSL::Digest::SHA256 return JOSE::JWA::PKCS1.rsaes_oaep_encrypt(rsa_oaep_md, plain_text, key) else raise ArgumentError, "unsupported RSA OAEP md: #{rsa_oaep_md.inspect}" end else raise ArgumentError, "unsupported RSA padding: #{rsa_padding.inspect}" end end |
#generate_key(fields) ⇒ Object
146 147 148 149 |
# File 'lib/jose/jwk/kty_rsa.rb', line 146 def generate_key(fields) kty, other_fields = JOSE::JWK::KTY_RSA.generate_key([:rsa, key.n.num_bits, key.e.to_i]) return kty, fields.delete('kid').merge(other_fields) end |
#key_encryptor(fields, key) ⇒ Object
151 152 153 |
# File 'lib/jose/jwk/kty_rsa.rb', line 151 def key_encryptor(fields, key) return JOSE::JWK::KTY.key_encryptor(self, fields, key) end |
#sign(message, digest_type, padding: :rsa_pkcs1_padding) ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/jose/jwk/kty_rsa.rb', line 155 def sign(, digest_type, padding: :rsa_pkcs1_padding) case padding when :rsa_pkcs1_padding return key.sign(digest_type.new, ) when :rsa_pkcs1_pss_padding if key.respond_to?(:sign_pss) digest_name = digest_type.new.name return key.sign_pss(digest_name, , salt_length: :digest, mgf1_hash: digest_name) else return JOSE::JWA::PKCS1.rsassa_pss_sign(digest_type, , key) end else raise ArgumentError, "unsupported RSA padding: #{padding.inspect}" end end |
#signer(fields = nil) ⇒ Object
171 172 173 174 175 176 177 178 179 |
# File 'lib/jose/jwk/kty_rsa.rb', line 171 def signer(fields = nil) if key.private? and fields and fields['use'] == 'sig' and not fields['alg'].nil? return JOSE::Map['alg' => fields['alg']] elsif key.private? return JOSE::Map['alg' => 'RS256'] else raise ArgumentError, "signing not supported for public keys" end end |
#to_key ⇒ Object
44 45 46 |
# File 'lib/jose/jwk/kty_rsa.rb', line 44 def to_key return key.__getobj__ end |
#to_map(fields) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/jose/jwk/kty_rsa.rb', line 48 def to_map(fields) if key.private? return fields. put('d', JOSE.urlsafe_encode64(key.d.to_s(2))). put('dp', JOSE.urlsafe_encode64(key.dmp1.to_s(2))). put('dq', JOSE.urlsafe_encode64(key.dmq1.to_s(2))). put('e', JOSE.urlsafe_encode64(key.e.to_s(2))). put('kty', 'RSA'). put('n', JOSE.urlsafe_encode64(key.n.to_s(2))). put('p', JOSE.urlsafe_encode64(key.p.to_s(2))). put('q', JOSE.urlsafe_encode64(key.q.to_s(2))). put('qi', JOSE.urlsafe_encode64(key.iqmp.to_s(2))). put('q', JOSE.urlsafe_encode64(key.q.to_s(2))) else return fields. put('e', JOSE.urlsafe_encode64(key.e.to_s(2))). put('kty', 'RSA'). put('n', JOSE.urlsafe_encode64(key.n.to_s(2))) end end |
#to_pem(password = nil) ⇒ Object
219 220 221 |
# File 'lib/jose/jwk/kty_rsa.rb', line 219 def to_pem(password = nil) return JOSE::JWK::PEM.to_binary(key, password) end |
#to_public_map(fields) ⇒ Object
69 70 71 |
# File 'lib/jose/jwk/kty_rsa.rb', line 69 def to_public_map(fields) return to_map(fields).except('d', 'dp', 'dq', 'p', 'q', 'qi', 'oth') end |
#to_thumbprint_map(fields) ⇒ Object
73 74 75 |
# File 'lib/jose/jwk/kty_rsa.rb', line 73 def to_thumbprint_map(fields) return to_public_map(fields).slice('e', 'kty', 'n') end |
#verifier(fields) ⇒ Object
181 182 183 184 185 186 187 |
# File 'lib/jose/jwk/kty_rsa.rb', line 181 def verifier(fields) if fields and fields['use'] == 'sig' and not fields['alg'].nil? return [fields['alg']] else return ['PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512'] end end |
#verify(message, digest_type, signature, padding: :rsa_pkcs1_padding) ⇒ Object
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/jose/jwk/kty_rsa.rb', line 189 def verify(, digest_type, signature, padding: :rsa_pkcs1_padding) case padding when :rsa_pkcs1_padding return key.verify(digest_type.new, signature, ) when :rsa_pkcs1_pss_padding if key.respond_to?(:verify_pss) digest_name = digest_type.new.name return key.verify_pss(digest_name, signature, , salt_length: :digest, mgf1_hash: digest_name) else return JOSE::JWA::PKCS1.rsassa_pss_verify(digest_type, , signature, key) end else raise ArgumentError, "unsupported RSA padding: #{padding.inspect}" end rescue OpenSSL::PKey::PKeyError # jruby raises this error if the signature is invalid false end |