Class: JSON::JWE
Defined Under Namespace
Classes: DecryptionFailed, InvalidFormat, UnexpectedAlgorithm
Constant Summary collapse
- NUM_OF_SEGMENTS =
5
Instance Attribute Summary collapse
-
#auth_data ⇒ Object
Returns the value of attribute auth_data.
-
#authentication_tag ⇒ Object
writeonly
Sets the attribute authentication_tag.
-
#cipher_text ⇒ Object
Returns the value of attribute cipher_text.
-
#content_encryption_key ⇒ Object
Returns the value of attribute content_encryption_key.
-
#encryption_key ⇒ Object
Returns the value of attribute encryption_key.
-
#iv ⇒ Object
Returns the value of attribute iv.
-
#jwe_encrypted_key ⇒ Object
writeonly
Sets the attribute jwe_encrypted_key.
-
#mac_key ⇒ Object
Returns the value of attribute mac_key.
-
#plain_text ⇒ Object
Returns the value of attribute plain_text.
-
#private_key_or_secret ⇒ Object
Returns the value of attribute private_key_or_secret.
-
#public_key_or_secret ⇒ Object
Returns the value of attribute public_key_or_secret.
Class Method Summary collapse
- .decode_compact_serialized(input, private_key_or_secret, algorithms = nil, encryption_methods = nil, _allow_blank_payload = false) ⇒ Object
- .decode_json_serialized(input, private_key_or_secret, algorithms = nil, encryption_methods = nil, _allow_blank_payload = false) ⇒ Object
Instance Method Summary collapse
- #as_json(options = {}) ⇒ Object
- #decrypt!(private_key_or_secret, algorithms = nil, encryption_methods = nil) ⇒ Object
- #encrypt!(public_key_or_secret) ⇒ Object
-
#initialize(input = nil) ⇒ JWE
constructor
A new instance of JWE.
- #to_s ⇒ Object
Methods included from JOSE
#secure_compare, #with_jwk_support
Constructor Details
#initialize(input = nil) ⇒ JWE
Returns a new instance of JWE.
25 26 27 |
# File 'lib/json/jwe.rb', line 25 def initialize(input = nil) self.plain_text = input.to_s end |
Instance Attribute Details
#auth_data ⇒ Object
Returns the value of attribute auth_data.
15 16 17 |
# File 'lib/json/jwe.rb', line 15 def auth_data @auth_data end |
#authentication_tag=(value) ⇒ Object
Sets the attribute authentication_tag
20 21 22 |
# File 'lib/json/jwe.rb', line 20 def authentication_tag=(value) @authentication_tag = value end |
#cipher_text ⇒ Object
Returns the value of attribute cipher_text.
15 16 17 |
# File 'lib/json/jwe.rb', line 15 def cipher_text @cipher_text end |
#content_encryption_key ⇒ Object
Returns the value of attribute content_encryption_key.
15 16 17 |
# File 'lib/json/jwe.rb', line 15 def content_encryption_key @content_encryption_key end |
#encryption_key ⇒ Object
Returns the value of attribute encryption_key.
15 16 17 |
# File 'lib/json/jwe.rb', line 15 def encryption_key @encryption_key end |
#iv ⇒ Object
Returns the value of attribute iv.
15 16 17 |
# File 'lib/json/jwe.rb', line 15 def iv @iv end |
#jwe_encrypted_key=(value) ⇒ Object
Sets the attribute jwe_encrypted_key
20 21 22 |
# File 'lib/json/jwe.rb', line 20 def jwe_encrypted_key=(value) @jwe_encrypted_key = value end |
#mac_key ⇒ Object
Returns the value of attribute mac_key.
15 16 17 |
# File 'lib/json/jwe.rb', line 15 def mac_key @mac_key end |
#plain_text ⇒ Object
Returns the value of attribute plain_text.
15 16 17 |
# File 'lib/json/jwe.rb', line 15 def plain_text @plain_text end |
#private_key_or_secret ⇒ Object
Returns the value of attribute private_key_or_secret.
15 16 17 |
# File 'lib/json/jwe.rb', line 15 def private_key_or_secret @private_key_or_secret end |
#public_key_or_secret ⇒ Object
Returns the value of attribute public_key_or_secret.
15 16 17 |
# File 'lib/json/jwe.rb', line 15 def public_key_or_secret @public_key_or_secret end |
Class Method Details
.decode_compact_serialized(input, private_key_or_secret, algorithms = nil, encryption_methods = nil, _allow_blank_payload = false) ⇒ Object
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/json/jwe.rb', line 262 def decode_compact_serialized(input, private_key_or_secret, algorithms = nil, encryption_methods = nil, _allow_blank_payload = false) unless input.count('.') + 1 == NUM_OF_SEGMENTS raise InvalidFormat.new("Invalid JWE Format. JWE should include #{NUM_OF_SEGMENTS} segments.") end jwe = new _header_json_, jwe.jwe_encrypted_key, jwe.iv, jwe.cipher_text, jwe.authentication_tag = input.split('.', NUM_OF_SEGMENTS).collect do |segment| begin Base64.urlsafe_decode64 segment rescue ArgumentError raise DecryptionFailed end end jwe.auth_data = input.split('.').first jwe.header = JSON.parse(_header_json_).with_indifferent_access unless private_key_or_secret == :skip_decryption jwe.decrypt! private_key_or_secret, algorithms, encryption_methods end jwe end |
.decode_json_serialized(input, private_key_or_secret, algorithms = nil, encryption_methods = nil, _allow_blank_payload = false) ⇒ Object
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
# File 'lib/json/jwe.rb', line 282 def decode_json_serialized(input, private_key_or_secret, algorithms = nil, encryption_methods = nil, _allow_blank_payload = false) input = input.with_indifferent_access jwe_encrypted_key = if input[:recipients].present? input[:recipients].first[:encrypted_key] else input[:encrypted_key] end compact_serialized = [ input[:protected], jwe_encrypted_key, input[:iv], input[:ciphertext], input[:tag] ].join('.') decode_compact_serialized compact_serialized, private_key_or_secret, algorithms, encryption_methods end |
Instance Method Details
#as_json(options = {}) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/json/jwe.rb', line 84 def as_json( = {}) case [:syntax] when :general { protected: Base64.urlsafe_encode64(header.to_json, padding: false), recipients: [{ encrypted_key: Base64.urlsafe_encode64(jwe_encrypted_key, padding: false) }], iv: Base64.urlsafe_encode64(iv, padding: false), ciphertext: Base64.urlsafe_encode64(cipher_text, padding: false), tag: Base64.urlsafe_encode64(authentication_tag, padding: false) } else { protected: Base64.urlsafe_encode64(header.to_json, padding: false), encrypted_key: Base64.urlsafe_encode64(jwe_encrypted_key, padding: false), iv: Base64.urlsafe_encode64(iv, padding: false), ciphertext: Base64.urlsafe_encode64(cipher_text, padding: false), tag: Base64.urlsafe_encode64(authentication_tag, padding: false) } end end |
#decrypt!(private_key_or_secret, algorithms = nil, encryption_methods = nil) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/json/jwe.rb', line 42 def decrypt!(private_key_or_secret, algorithms = nil, encryption_methods = nil) raise UnexpectedAlgorithm.new('Unexpected alg header') unless algorithms.blank? || Array(algorithms).include?(alg) raise UnexpectedAlgorithm.new('Unexpected enc header') unless encryption_methods.blank? || Array(encryption_methods).include?(enc) self.private_key_or_secret = with_jwk_support private_key_or_secret self.content_encryption_key = decrypt_content_encryption_key self.mac_key, self.encryption_key = derive_encryption_and_mac_keys verify_cbc_authentication_tag! if cbc? cipher.decrypt cipher.key = encryption_key cipher.iv = iv # NOTE: 'iv' has to be set after 'key' for GCM if gcm? # https://github.com/ruby/openssl/issues/63 raise DecryptionFailed.new('Invalid authentication tag') if authentication_tag.length < 16 cipher.auth_tag = authentication_tag cipher.auth_data = auth_data end begin self.plain_text = cipher.update(cipher_text) + cipher.final rescue OpenSSL::OpenSSLError # Ensure that the same error is raised for invalid PKCS7 padding # as for invalid signatures. This prevents padding-oracle attacks. raise DecryptionFailed end self end |
#encrypt!(public_key_or_secret) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/json/jwe.rb', line 29 def encrypt!(public_key_or_secret) self.public_key_or_secret = with_jwk_support public_key_or_secret cipher.encrypt self.content_encryption_key = generate_content_encryption_key self.mac_key, self.encryption_key = derive_encryption_and_mac_keys cipher.key = encryption_key self.iv = cipher.random_iv # NOTE: 'iv' has to be set after 'key' for GCM self.auth_data = Base64.urlsafe_encode64 header.to_json, padding: false cipher.auth_data = auth_data if gcm? self.cipher_text = cipher.update(plain_text) + cipher.final self end |
#to_s ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/json/jwe.rb', line 72 def to_s [ header.to_json, jwe_encrypted_key, iv, cipher_text, authentication_tag ].collect do |segment| Base64.urlsafe_encode64 segment.to_s, padding: false end.join('.') end |