附录2
签名验证
- Java
- Node.js
- Python
- .Net
- PHP
第 1 步:导入所需的包
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
第 2 步:从公钥字节创建一个PublicKey对象
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyBytes));
第 3 步:Create a Signature object and initialize it with the public key
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(publicKey);
第 4 步:将除 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();
第 5 步:使用消息字节更新 Signature 对象
signature.update(messageBytes);
第 6 步: 将 signedMessage 转换为字节并验证它
boolean verified = signature.verify(signedMessageBytes);
第 1 步:导入所需的包
import forge from "node-forge";
第 2 步:从公钥字节创建一个PublicKey对象
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);
第 3 步:将除signedMessage 之外的所有参数作为字符串
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);
第 4 步:验证签名
const md = forge.md.sha256.create();
md.update(jsonString, "utf8");
const verified = rsaPubicKey.verify(md.digest().bytes(), byteBuffer);
第 1 步:导入所需的包
import cryptography
第 2 步:从您的公钥创建 RSAPublicKey 对象
public_key = cryptography.hazmat.primitives.asymmetric.RSAPublicKey.load_pem_public_key(
open("public_key.pem").read()
)
第 3 步:创建 PKCS1v15 填充对象
padding = cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15()
第 4 步:创建 SHA256 哈希对象
hasher = cryptography.hazmat.primitives.hashes.SHA256()
第 5 步:将除signedMessage 之外的所有参数作为字符串
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"
第 6 步: 使用 verify() 方法来验证签名
verified = public_key.verify(
signature,
hasher.update(message).digest(),
padding=padding,
)