Appendix 2
Signature Verification
- Java
- Node.js
- Python
- .Net
- PHP
Step 1 : Import the required packages
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
Step 2 : Create a PublicKey
object from the public key bytes
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyBytes));
Step 3 : Create a Signature object and initialize it with the public key
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(publicKey);
Step 4 : Convert all parameters into bytes except signedMessage
response.setACQ("FNX");
response.setDeviceBrandModel("SB-001");
response.setDeviceID("SB000000001");
response.setLang("EN");
response.setTrxRefNo("FNX202302170100000000000000001");
response.setTrxCurr("MYR");
response.setTrxAmt("100.00");
response.setTrxDateTms("20230217121212236");
response.setTrxPymtBrand("PN");
response.setMID("000010000010440");
response.setTID("60003614");
Gson gson = new Gson();
String jsonStr = gson.toJson(response);
byte[] messageBytes = jsonStr.getBytes();
Step 5 : Update the Signature object with the message bytes
signature.update(messageBytes);
Step 6 : Convert signedMessage
to bytes and verify it
boolean verified = signature.verify(signedMessageBytes);
Step 1 : Import the required packages
import forge from "node-forge";
Step 2 : Create a PublicKey
object from the public key bytes
const publicKeyPath = "key/public.key";
const fetchPublicKey = async (path) => {
try {
const response = await fetch(path);
const publicKey = await response.text();
return publicKey;
} catch (error) {
//to do ...
}
};
const publicKey = await fetchPublicKey(publicKeyPath);
const rsaPubicKey = forge.pki.publicKeyFromPem(publicKey);
Step 3 : Put all parameters except signedMessage
as string
const response = {
ACQ: "FNX",
deviceBrandModel: "SB-001",
deviceID: "SB000000001",
lang: "EN",
trxRefNo: "FNX202302170100000000000000001",
trxCurr: "MYR",
trxAmt: "100.00",
trxDateTms: "20230217121212236",
trxPymtBrand: "PN",
MID: "000010000010440",
TID: "60003614"
};
const json = JSON.stringify(request);
const jsonString = `${json}`;
const signature = "68acc11449277468cb5e619f16bcff62f5448fa3911a462fd52abadaf4bc8f3effb";
function hexToBytes(hex) {
const bytes = [];
for (let i = 0; i < hex.length; i += 2) {
bytes.push(parseInt(hex.substr(i, 2), 16));
}
return new Uint8Array(bytes);
}
const byteArray = hexToBytes(signature);
const md = forge.md.sha256.create();
md.update(jsonString, "utf8");
const verified = rsaPubicKey.verify(md.digest().bytes(), byteArray);
Step 4 : Verify the signature
const md = forge.md.sha256.create();
md.update(jsonString, "utf8");
const verified = rsaPubicKey.verify(md.digest().bytes(), byteBuffer);
Step 1 : Import the required packages
import cryptography
Step 2 : Create an RSAPublicKey
object from your public key
public_key = cryptography.hazmat.primitives.asymmetric.RSAPublicKey.load_pem_public_key(
open("public_key.pem").read()
)
Step 3 : Create a PKCS1v15
padding object
padding = cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15()
Step 4 : Create a SHA256
hash object
hasher = cryptography.hazmat.primitives.hashes.SHA256()
Step 5 : Put all parameter except signedMessage as string
request_data = OrderedDict()
request_data["ACQ"] = "FNX"
request_data["deviceBrandModel"] = "SB-001"
request_data["deviceID"] = "SB000000001"
request_data["lang"] = "EN"
request_data["trxRefNo"] = "FNX202302170100000000000000001"
request_data["trxCurr"] = "MYR"
request_data["trxAmt"] = "100.00"
request_data["trxDateTms"] = "20230217121212236"
request_data["trxPymtBrand"] = "PN"
request_data["MID"] = "000010000010440"
request_data["TID"] = "60003614"
json_string = json.dumps(request_data, separators=(",", ":"))
message = f"{json_string}"
signature = "68acc11449277468cb5e619f16bcff62f5448fa3911a462fd52abadaf4bc8f3effb"
Step 6 : Use the verify() method to verify the signature
verified = public_key.verify(
signature,
hasher.update(message).digest(),
padding=padding,
)
Step 1 : Import the required packages
using System.Security.Cryptography;
Step 2 : Create a PublicKey
object from the public key bytes
var reader = System.IO.File.ReadAllText(@"E:\xxx\xxx\public.key");
RSA rsa = RSA.Create();
byte[] pubKey = Convert.FromBase64String(reader.Replace("-----BEGIN PUBLIC KEY-----", string.Empty)
.Replace("-----END PUBLIC KEY-----", string.Empty)
.Trim());
rsa.ImportSubjectPublicKeyInfo(pubKey, out _);
Step 3 : Convert all parameters except signedMessage
to strings
request.ACQ = "FNX";
request.deviceBrandModel = "SB-001";
request.deviceID = "SB000000001";
request.lang = "EN";
request.trxRefNo = "FNX202302170100000000000000001";
request.trxCurr = "MYR";
request.trxAmt = "100.00";
request.trxDateTms = "20230217121212236";
request.trxPymtBrand = "PN";
request.MID = "000010000010440";
request.TID = "60003614";
string json = JsonConvert.SerializeObject(request);
string jsonString = json;
string signature = "68acc11449277468cb5e619f16bcff62f5448fa3911a462fd52abadaf4bc8f3effb";
Step 4 : Verify the signature
static byte[] HexStringToBytes(string hexString)
{
int numberChars = hexString.Length;
byte[] bytes = new byte[numberChars / 2];
for (int i = 0; i < numberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16);
}
return bytes;
}
bool verify = rsa.VerifyData(Encoding.UTF8.GetBytes(jsonString), HexStringToBytes(signature), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
Step 1 : Import the OpenSSL extension
require_once 'vendor/autoload.php';
Step 2 : Create a new OpenSSL public key
$publicKeyFNXLocation = file_get_contents('key/xxx/xxx/public.key');
$publicKeyFNX = openssl_pkey_get_public($publicKeyFNXLocation);
$publicKeyDetailsFNX = openssl_pkey_get_details($publicKeyFNX);
$publicKeyPEM = $publicKeyDetailsFNX['key'];
Step 3 : Convert all parameters, except signedMessage
, to strings
$request->ACQ = "FNX";
$request->deviceBrandModel = "SB-001";
$request->deviceID = "SB000000001";
$request->lang = "EN";
$request->trxRefNo = "FNX202302170100000000000000001";
$request->trxCurr = "MYR";
$request->trxAmt = "100.00";
$request->trxDateTms = "20230217121212236";
$request->trxPymtBrand = "PN";
$request->MID = "000010000010440";
$request->TID = "60003614";
$jsonStringResponse = json_encode($paymentResponse);
$jsonResponse = json_decode($jsonStringResponse);
$updateJsonResponse = json_encode($jsonResponse);
$minifiedJsonResponse = json_encode(json_decode($updateJsonResponse));
$dataResponse = $minifiedJsonResponse;
$minifiedJson = json_encode(json_decode($updateJson));
$decodedSignedMessage = '68acc11449277468cb5e619f16bcff62f5448fa3911a462fd52abadaf4bc8f3effb';
$decodedSignature = hex2bin($decodedUrl);
Step 4 : Verify the signature
$verifyResponse = openssl_verify($dataResponse, $decodedSignature, $publicKeyPEM, OPENSSL_ALGO_SHA256);