Skip to content

Instantly share code, notes, and snippets.

@elricstorm
Created June 19, 2011 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elricstorm/1034524 to your computer and use it in GitHub Desktop.
Save elricstorm/1034524 to your computer and use it in GitHub Desktop.
# @my_url = 'http://localhost:3000/zong/callback?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'
def callback_test
require 'openssl'
require 'base64'
@parameters = params
@signature = params[:signature]
# Rebuild URL
rebuilturl = "?"
firstelement = true
@parameters.sort.each do |p|
if firstelement == true
# removing controller and action parameters
unless p[0].to_s == 'controller' || p[0].to_s == 'action'
rebuilturl << "#{p[0].to_s}=#{p[1].to_s}"
firstelement = false
end
else
unless p[0].to_s == 'controller' || p[0].to_s == 'action'
rebuilturl << '&' << "#{p[0].to_s}=#{p[1].to_s}"
end
end
end
@rebuilturl = rebuilturl
# Verify Signature
publickeyid = OpenSSL::PKey::RSA.new(File.read("#{Rails.root}/certs/zong.pem"))
@pem = publickeyid
@verified = publickeyid.verify( OpenSSL::Digest::SHA1.new, Base64.decode64(@signature), @rebuilturl )
@verified_class = @verified.class
if @verified == true
return true
else
return false
end
end
# OUTPUT SHOWS THE FOLLOWING
=begin
PEM = -----BEGIN RSA PUBLIC KEY----- MIGJAoGBAK3xYYUPYcfWwdt22tnQyyke55UNva+OTYbXWoujFmJN6F9FOaUqK8Uy R0L/g8y0XvdniSMcOv7uVT1vgOaRw3JnTcOytG251j1wZaHRxgIKw4ONJyNIIql9 M9SP/dHF7qFyqF8hbDde525oAsGdPfU1Hj31Ch2nzn1GcGm7BKJ5AgMBAAE= -----END RSA PUBLIC KEY-----
Params = {"consumerCurrency"=>"USD", "consumerPrice"=>"9.9900", "itemRef"=>"9.9900_USD", "method"=>"MOBILE", "msisdn"=>"+15555550218", "outPayment"=>"6.1800 USD", "signature"=>"rYLptV7HOnSn82qEV6uYc01ZwO4iGMN3Phag2c5z85Gdp/nGJV4S51uRSnEjTm3+EP7mcAsP0wG06vro6XP2OR0yPL5ohxWTqpKKu8Q2uEOe5sIxU7zoaOowbILTVfaFP66yLRiKz/nlqs3wRCY3HeqtuZQfm/NfdDruRo9cEnM=", "signatureVersion"=>"1", "simulated"=>"true", "status"=>"COMPLETED", "transactionRef"=>"1_2011_06191550", "controller"=>"store", "action"=>"callback_test"}
Signature = rYLptV7HOnSn82qEV6uYc01ZwO4iGMN3Phag2c5z85Gdp/nGJV4S51uRSnEjTm3+EP7mcAsP0wG06vro6XP2OR0yPL5ohxWTqpKKu8Q2uEOe5sIxU7zoaOowbILTVfaFP66yLRiKz/nlqs3wRCY3HeqtuZQfm/NfdDruRo9cEnM=
Rebuilt URL = ?consumerCurrency=USD&consumerPrice=9.9900&itemRef=9.9900_USD&method=MOBILE&msisdn=+15555550218&outPayment=6.1800 USD&signature=rYLptV7HOnSn82qEV6uYc01ZwO4iGMN3Phag2c5z85Gdp/nGJV4S51uRSnEjTm3+EP7mcAsP0wG06vro6XP2OR0yPL5ohxWTqpKKu8Q2uEOe5sIxU7zoaOowbILTVfaFP66yLRiKz/nlqs3wRCY3HeqtuZQfm/NfdDruRo9cEnM=&signatureVersion=1&simulated=true&status=COMPLETED&transactionRef=1_2011_06191550
Class = FalseClass
Verified = false
=end
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
The public key in x509 / PEM format can be found here:
http://pay01.zong.com/zongpay/docs/pubkey_v1.pem
<?
function verifySignature ($qs) {
$pem = '-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCt8WGFD2HH1sHbdtrZ0MspHueVDb2vjk2G11qLoxZiTehfRTmlKivFMkdC/4PMtF73Z4kjHDr+7lU9b4DmkcNyZ03DsrRtudY9cGWh0cYCCsODjScjSCKpfTPUj/3Rxe6hcqhfIWw3XuduaALBnT31NR499Qodp859RnBpuwSieQIDAQAB-----END PUBLIC KEY-----';
//Grab Signature Value
preg_match("/signature=(.*?)&/", $qs, $matches);
$signature = urldecode($matches[1]);
$qs=preg_replace("/signature=([Verify signature^&]*)/", "signature=", $qs);
//Grab Parameters, insert into array for sorting
$parameters = array();
$token = strtok($qs, "&");
while ($token != false) {
$parameters[] = $token;
$token = strtok("&"); }
//sort array
sort($parameters);
//Rebuild URL
$rebuiltURL = "?";
$firstElement = true;
foreach ($parameters as $p) {
if($firstElement) {
$rebuiltURL .= $p;
$firstElement = false;
} else {
$rebuiltURL .= "&" . $p;
}
}
$publickeyid = openssl_get_publickey($pem);
$verified = openssl_verify($rebuiltURL, base64_decode($signature), $publickeyid);
openssl_free_key($publickeyid);
if($verified == 1) {
return true;
} else {
return false;
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment