Unable to get openssl to verify a callback signature

I’m implementing a mobile payment solution and the provider only has
instructions for PHP and Python. I wrote a Ruby version of the script,
but it’s not working 100%. I have the full ruby version I created,
along with text notes of their implementation instructions and a copy of
a working PHP example.

It’s located here: test.rb · GitHub

In my ruby file, I provided all of the code being used, the URL test I’m
passing to my callback, and the results are located at the bottom of the
file.

The problem is that the verification is returning false and it more than
likely has to do with some step I’m missing in the translation.

Any help would be appreciated. I will be posting this to both the ruby
and ruby on rails forums as part of this deals with Rails, and the other
part deals with how to understand how to do openssl verification in
ruby.

Thank you.

So, I feel like I’m making some headway but I’m still doing something
wrong. Here is the new gist:

Based on the instructions provided:

The URL with all parameters being sent looks like this:

?consumerCurrency=USD&consumerPrice=9.9900&itemRef=9.9900_USD&method=MOBILE&msisdn=%2B15555550218&outPayment=6.1800+USD&signature=rYLptV7HOnSn82qEV6uYc01ZwO4iGMN3Phag2c5z85Gdp%2FnGJV4S51uRSnEjTm3%2BEP7mcAsP0wG06vro6XP2OR0yPL5ohxWTqpKKu8Q2uEOe5sIxU7zoaOowbILTVfaFP66yLRiKz%2Fnlqs3wRCY3HeqtuZQfm%2FNfdDruRo9cEnM%3D&signatureVersion=1&simulated=true&status=COMPLETED&transactionRef=1_2011_06191550

I am capturing the signature and then isolating and removing the
signature, controller, and action params so I’m left with a basic list
of parameters that were sent to me from the provider.

So, according to their steps:

How we prepared the signature

  1. We take the query string including the leading “?” symbol
  2. The parameter signature= (the value is empty) is appended to the
    query string
  3. The parameter signatureVersion=1 is appended to the query string
  4. The parameters are ordered alphabetically by name and value
  5. The signature is generated using SHA1 with RSA and with our private
    key
  6. The generated value is coded in BASE64 and added in place of the
    empty value of the signature parameter.

So, they are saying that they are removing the signature and replacing
it with a signature=, along with everything listed here, and then
sorting the parameters alphabetically by name and value.

Here is the rebuilt_url once I’ve done all of that:

Rebuilt URL =
?consumerCurrency=USD&consumerPrice=9.9900&itemRef=9.9900_USD&method=MOBILE&msisdn=+15555550218&outPayment=6.1800
USD&signature=&signatureVersion=1&simulated=true&status=COMPLETED&transactionRef=1_2011_06191550

So, looking over their list I have everything so far.

The problem appears to be with the following code, and I"m not sure what
I’m doing wrong:

Verify Signature

publickeyid =
OpenSSL::PKey::RSA.new(File.read(“#{Rails.root}/certs/zong.pem”))
@verified = publickeyid.verify( OpenSSL::Digest::SHA1.new,
Base64.decode64(@signature), @rebuilturl )

if @verified == true
return true
else
return false
end

According to their instructions they are encoding the signature with
Base64 so I’m trying to verify against decoding that signature and
comparing it to the now rebuilturl string that houses everything sorted
according to what they said.

Everything works fine except for the verification which comes up false.
I could really use some help from someone that understands OpenSSL a lot
better than I do.

Thanks again.