Skip to content

Gem signs with Digest::SHA1 and hardcodes version 3 — is API v7 (new hashing algorithm) supported or planned? #11

Description

@yaroslavrick

Hi! Evaluating this SDK for a production integration and I ran into a mismatch between the gem and the current API version. Sharing the details so the question is actionable.

The mismatch

The docs at https://www.liqpay.ua/uk/doc/api/internet_acquiring show a notice:

API Liqpay оновлено до версії 7. Дана версія є більш захищеною і підтримує новий алгоритм хешування. Попередня версія api 3 не була відключена і також підтримується системою.

And https://www.liqpay.ua/uk/doc documents the v7 signature as:

signature = base64_encode( sha3-256( private_key + data + private_key) )

But this gem (master) signs with SHA-1 and hardcodes version = 3:

# lib/liqpay/coder.rb
def encode_signature(param)
  sha1 = Digest::SHA1.digest(param)
  #Base64.strict_encode64(sha1)
  encode64(sha1)
end
# lib/liqpay/config.rb
def initialize
  @private_key = ENV['LIQPAY_PRIVATE_KEY']
  @public_key  = ENV['LIQPAY_PUBLIC_KEY']
  @version = 3
end
# lib/liqpay/liqpay.rb
def str_to_sign(str)
  warn 'DEPRECATION WARNING: the method str_to_sign is deprecated. Use encode_signature insted.'
  Coder.encode_signature str
end

Verification against your own documented example

Using the worked example from https://www.liqpay.ua/uk/doc:

private_key = a4825234f4bae72a0be04eafe9e8e2bada209255
json_string = {"public_key":"i00000000","version":7,"action":"pay","amount":"3","currency":"UAH","description":"test","order_id":"000001"}
data        = eyJwdWJsaWNfa2V5IjoiaTAwMDAwMDAwIiwidmVyc2lvbiI6NywiYWN0aW9uIjoicGF5IiwiYW1vdW50IjoiMyIsImN1cnJlbmN5IjoiVUFIIiwiZGVzY3JpcHRpb24iOiJ0ZXN0Iiwib3JkZXJfaWQiOiIwMDAwMDEifQ==

Expected signature per the docs: 0adgJ8F2Ds5HCVkcz4AlmdLMRoIJf7IxsL3QmeFRz/s=

Algorithm over private_key + data + private_key Result Matches docs?
sha1 (what this gem uses) CZQ2WPZ4+rJnKdg5BT9lSsJtXZk=
sha256 Apq78ngy28oYukY0oIKFWEsJJPMxAKiuBshdBLO0bAI=
sha3-256 0adgJ8F2Ds5HCVkcz4AlmdLMRoIJf7IxsL3QmeFRz/s= ✅ byte for byte

So the gem cannot produce a valid version: 7 signature as-is.

Questions

  1. Is version: 7 / SHA3-256 supported or planned in this SDK? Or is the gem intentionally frozen on the still-supported v3?
  2. Is this repository maintained? Latest commit on master is from 2023-10-27, and several docs pages now describe v7 behaviour the gem does not implement.
  3. encode64 vs strict_encode64 in Coder#encode_signature: the strict_encode64 line is commented out and encode64(sha1) is called instead. If that resolves to stdlib Base64.encode64, it appends a trailing newline (and wraps at 60 chars), which breaks a byte comparison against the signature returned by LiqPay. Could you confirm which behaviour is intended?
  4. Distribution: this gem does not appear to be published on RubyGems, and the liqpay name there belongs to an unrelated third-party library. Is installing from git the intended path, or is a RubyGems release planned? Right now it is easy to install the wrong liqpay by accident.
  5. Ruby examples in the docs (e.g. liqpay.str_to_sign(PRIVATE_KEY + data + PRIVATE_KEY)) use a method this gem itself marks as deprecated, and they follow the v3 signature scheme. Are there plans to update the Ruby snippets in the documentation for v7?

Note for anyone implementing v7 in Ruby

SHA3-256 is not in the Digest stdlib, and via OpenSSL::Digest its availability depends on how Ruby was linked. It works on OpenSSL 3.x, but raises on LibreSSL builds (e.g. the system Ruby on macOS):

OpenSSL::Digest.new('SHA3-256')
# RuntimeError: Unsupported digest algorithm (SHA3-256)

Worth documenting, since it fails at runtime rather than at install time. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions