Module: Buckaruby::Signature
- Defined in:
- lib/buckaruby/signature.rb
Overview
Calculate a signature based on the parameters of the payment request or response. -> see BPE 3.0 Gateway NVP, chapter 4 ‘Digital Signature’
Constant Summary collapse
- CHAR_ORDER =
Excerpt from the Buckaroo documentation, chapter 4 ‘Digital Signature’:
In the payment engine, the used lexical sort algorithm uses the following order: symbols first, then numbers, then case insensitive letters. Also, a shorter string that is identical to the beginning of a longer string, comes before the longer string. Take for example the following, comma separated, list which has been sorted: a_a, a0, a0a, a1a, aaA, aab, aba, aCa
'_01234567890abcdefghijklmnopqrstuvwxyz'
Class Method Summary collapse
- .generate(config, params) ⇒ Object
- .generate_params_string(secret, params) ⇒ Object
- .order_signature_params(params) ⇒ Object
-
.safe_equals?(signature, other_signature) ⇒ Boolean
Constant time string comparison.
-
.verify!(config, params) ⇒ Object
Check the signature from the Buckaroo response with our generated signature.
Class Method Details
.generate(config, params) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/buckaruby/signature.rb', line 11 def generate(config, params) string = generate_params_string(config.secret, params) case config.hash_method when :sha1 Digest::SHA1.hexdigest(string) when :sha256 Digest::SHA256.hexdigest(string) when :sha512 Digest::SHA512.hexdigest(string) else raise ArgumentError, "Invalid hash method provided: #{config.hash_method}" end end |
.generate_params_string(secret, params) ⇒ Object
26 27 28 29 30 31 32 33 |
# File 'lib/buckaruby/signature.rb', line 26 def generate_params_string(secret, params) sign_params = params.select { |key, _value| key.to_s.upcase.start_with?('BRQ_', 'ADD_', 'CUST_') && key.to_s.casecmp('BRQ_SIGNATURE').nonzero? } sign_params = order_signature_params(sign_params) string = sign_params.map { |param| "#{param[0]}=#{param[1]}" }.join string << secret string end |
.order_signature_params(params) ⇒ Object
43 44 45 46 47 |
# File 'lib/buckaruby/signature.rb', line 43 def order_signature_params(params) params.sort_by do |key, _value| key.to_s.downcase.each_char.map { |c| CHAR_ORDER.index(c) } end end |
.safe_equals?(signature, other_signature) ⇒ Boolean
Constant time string comparison.
60 61 62 63 64 |
# File 'lib/buckaruby/signature.rb', line 60 def safe_equals?(signature, other_signature) check = signature.bytesize ^ other_signature.bytesize signature.bytes.zip(other_signature.bytes) { |x, y| check |= x ^ y.to_i } check.zero? end |
.verify!(config, params) ⇒ Object
Check the signature from the Buckaroo response with our generated signature.
50 51 52 53 54 55 56 57 |
# File 'lib/buckaruby/signature.rb', line 50 def verify!(config, params) sent_signature = params.find { |key, _value| key.to_s.casecmp('BRQ_SIGNATURE').zero? }&.last generated_signature = Signature.generate(config, params) if sent_signature.nil? || generated_signature.nil? || !safe_equals?(sent_signature, generated_signature) raise SignatureException.new(sent_signature, generated_signature) end end |