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
193 194 195 196 197 198 199 200 201 |
# File 'lib/jose/jwk/kty_rsa.rb', line 193 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 |
# 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) rsa = OpenSSL::PKey::RSA.new rsa.d = OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['d']), 2) rsa.dmp1 = OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['dp']), 2) rsa.dmq1 = OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['dq']), 2) rsa.e = OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['e']), 2) rsa.n = OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['n']), 2) rsa.p = OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['p']), 2) rsa.q = OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['q']), 2) rsa.iqmp = OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['qi']), 2) 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 rsa = OpenSSL::PKey::RSA.new rsa.e = OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['e']), 2) rsa.n = OpenSSL::BN.new(JOSE.urlsafe_decode64(fields['n']), 2) 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
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/jose/jwk/kty_rsa.rb', line 124 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, exponent_size)) 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
74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/jose/jwk/kty_rsa.rb', line 74 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
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/jose/jwk/kty_rsa.rb', line 88 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
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/jose/jwk/kty_rsa.rb', line 106 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
140 141 142 143 |
# File 'lib/jose/jwk/kty_rsa.rb', line 140 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
145 146 147 |
# File 'lib/jose/jwk/kty_rsa.rb', line 145 def key_encryptor(fields, key) return JOSE::JWK::KTY.key_encryptor(self, fields, key) end |
#sign(message, digest_type, padding: :rsa_pkcs1_padding) ⇒ Object
149 150 151 152 153 154 155 156 157 158 |
# File 'lib/jose/jwk/kty_rsa.rb', line 149 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 return JOSE::JWA::PKCS1.rsassa_pss_sign(digest_type, , key) else raise ArgumentError, "unsupported RSA padding: #{padding.inspect}" end end |
#signer(fields = nil) ⇒ Object
160 161 162 163 164 165 166 167 168 |
# File 'lib/jose/jwk/kty_rsa.rb', line 160 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
39 40 41 |
# File 'lib/jose/jwk/kty_rsa.rb', line 39 def to_key return key.__getobj__ end |
#to_map(fields) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/jose/jwk/kty_rsa.rb', line 43 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
203 204 205 |
# File 'lib/jose/jwk/kty_rsa.rb', line 203 def to_pem(password = nil) return JOSE::JWK::PEM.to_binary(key, password) end |
#to_public_map(fields) ⇒ Object
64 65 66 |
# File 'lib/jose/jwk/kty_rsa.rb', line 64 def to_public_map(fields) return to_map(fields).except('d', 'dp', 'dq', 'p', 'q', 'qi', 'oth') end |
#to_thumbprint_map(fields) ⇒ Object
68 69 70 |
# File 'lib/jose/jwk/kty_rsa.rb', line 68 def to_thumbprint_map(fields) return to_public_map(fields).slice('e', 'kty', 'n') end |
#verifier(fields) ⇒ Object
170 171 172 173 174 175 176 |
# File 'lib/jose/jwk/kty_rsa.rb', line 170 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
178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/jose/jwk/kty_rsa.rb', line 178 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 return JOSE::JWA::PKCS1.rsassa_pss_verify(digest_type, , signature, key) else raise ArgumentError, "unsupported RSA padding: #{padding.inspect}" end rescue OpenSSL::PKey::PKeyError # jruby raises this error if the signature is invalid false end |