Module: SharedBroker::Cipher
- Defined in:
- lib/shared_broker/cipher.rb
Defined Under Namespace
Classes: DecryptionError
Constant Summary collapse
- ALGORITHM =
"aes-256-gcm"
Class Method Summary collapse
Class Method Details
.decrypt(payload_hash, key) ⇒ 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 |
# File 'lib/shared_broker/cipher.rb', line 42 def self.decrypt(payload_hash, key) return payload_hash unless payload_hash.is_a?(Hash) && payload_hash[:_encrypted] return payload_hash unless key cipher = OpenSSL::Cipher.new(ALGORITHM) cipher.decrypt cipher.key = key cipher.iv = Base64.strict_decode64(payload_hash[:_iv]) cipher.auth_tag = Base64.strict_decode64(payload_hash[:_auth_tag]) encrypted_bytes = Base64.strict_decode64(payload_hash[:_data]) decrypted_json = cipher.update(encrypted_bytes) + cipher.final decrypted_data = JSON.parse(decrypted_json, symbolize_names: true) # Merge back the unencrypted metadata = payload_hash.select { |k, _| k.to_s.start_with?("_") } .delete(:_encrypted) .delete(:_iv) .delete(:_auth_tag) .delete(:_data) decrypted_data.merge() rescue => e raise DecryptionError, "Failed to decrypt payload. Error: #{e.}. Offending payload: #{payload_hash.inspect}" end |
.encrypt(payload_hash, key) ⇒ Object
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 |
# File 'lib/shared_broker/cipher.rb', line 13 def self.encrypt(payload_hash, key) return payload_hash unless key unless payload_hash.is_a?(Hash) raise ArgumentError, "Expected payload_hash to be a Hash, got #{payload_hash.class} with value #{payload_hash.inspect}" end # We don't want to encrypt correlation ID or special metadata keys if we want the broker to read them, # but we want to encrypt the actual payload data. # Let's extract metadata starting with underscore and encrypt the rest. = payload_hash.select { |k, _| k.to_s.start_with?("_") } data_to_encrypt = payload_hash.reject { |k, _| k.to_s.start_with?("_") } cipher = OpenSSL::Cipher.new(ALGORITHM) cipher.encrypt cipher.key = key iv = cipher.random_iv encrypted_data = cipher.update(data_to_encrypt.to_json) + cipher.final auth_tag = cipher.auth_tag .merge( _encrypted: true, _iv: Base64.strict_encode64(iv), _auth_tag: Base64.strict_encode64(auth_tag), _data: Base64.strict_encode64(encrypted_data) ) end |