You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP转Ruby实现SHA512哈希签名结果不一致求助

Fixing SHA512 Signature Mismatch Between PHP and Ruby

Let's break down why your Ruby code isn't matching the PHP signature, and fix it step by step:

Key Differences Causing Mismatch

  1. Hash Algorithm Choice: PHP uses a plain SHA-512 hash of the concatenated query string + secret, but your Ruby code incorrectly uses HMAC-SHA512—this is a distinct algorithm that treats the secret as a cryptographic key instead of just appending it to the input string.
  2. Query String Encoding: PHP's http_build_query converts spaces to + by default, while Ruby's native to_query converts spaces to %20. This subtle difference changes the raw input to the hash function, resulting in completely different signatures.

Corrected Ruby Code

require 'digest'
require 'uri'

secret = '70b49742-adbf-4ac5-9cd6-5ded5c39aa83'
fields = {
    'merchant_reference' => '1234567890',
    'currency' => 'USD',
    'amount' => '100.00',
    'customer_ip'=> '123.123.123.123',
    'customer_name' => 'Someone Buying',
    'customer_address'=> '1, Bay Street',
    'customer_phone' => '0123123123',
    'customer_email' => 'someone@gmail.com',
    'customer_country' => 'US',
    'return_url' => 'https://demo.shop.com/payment/return'
}

# 1. Sort fields by key to match PHP's ksort behavior
sorted_fields = fields.sort.to_h

# 2. Generate query string that matches PHP's http_build_query output
# URI.encode_www_form handles proper URL encoding, then replace %20 with + to match PHP's default space handling
query_string = URI.encode_www_form(sorted_fields).gsub('%20', '+')

# 3. Concatenate query string with secret, then compute plain SHA512 hash
sign = Digest::SHA512.hexdigest(query_string + secret)

puts sign # This will output your expected PHP signature

Explanation of Changes

  • Swapped HMAC for Plain SHA512: We use Digest::SHA512.hexdigest instead of OpenSSL::HMAC.hexdigest to mirror PHP's hash('SHA512', ...) behavior—this just hashes the raw concatenated string, no key-based HMAC logic involved.
  • Fixed Encoding Discrepancy: URI.encode_www_form properly encodes key-value pairs, then we replace %20 with + to replicate how PHP handles spaces in query strings by default.
  • Sorted Fields Correctly: fields.sort.to_h sorts the hash by key names in ascending order, which is exactly what PHP's ksort function does.

Running this code will produce the expected signature: 750b059c76657abf2a2b73e0c8d919ec5739f83a713fcdce1fd22f2b3f45446d554bc26d6508972ba16cf2c4e55ec46861d966ba976effaeba9802b829164417

内容的提问来源于stack exchange,提问作者user3206743

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:51:53