我正在尝试验证Parse.com云代码上的RSA签名。基本上,我正在尝试在服务器上进行Android应用内购买的收据验证。
Parse.com加密模块不支持验证方法。所以我在网上找到了一个我导入的图书馆。
var KJUR = require("cloud/jsrsasign-4.7.0/npm/lib/jsrsasign.js");
var verifier = new KJUR.crypto.Signature({alg: "SHA1withRSA", prov: "cryptojs/jsrsa"});
verifier.initVerifyByCertificatePEM(publicKey);
verifier.updateString(purchaseData);
//verifier.updateHex(hexValue);
var result = verifier.verify(signature);
我做错了什么,但真的说不出是什么。我可能把签名、publicKey和purchaseData放错了地方。
purchaseData看起来是这样的:(根据Android规范,我更改了数据)
var purchaseData = {
orderID: "12999763169854705758.1300523466622834",
packageName: "com.blabla.bla",
productID: e.purchase.SKU,
purchaseTime: new moment(time).valueOf(),
purchaseState: 0,
developerPayload: "74571d75-98b8-4327-942d-5379309c9033",
purchaseToken: "klsDmifojfknmbojimkkkdkm.AO-J1OyXvZ3RH1aPiPD2MIdOUu00FrCnuTCjl1-K3ZD4Puu0zXDPTOAKH3Dc1hq1DZwiNI-AgXwW18gDV3eU9kXCR1IwhADLvVeOSkyu5kzdUBoVNdA42Zc"
};
我得到以下错误:
Result: TypeError: Cannot call method 'bitLength' of undefined
at RSAKey._rsasign_verifyWithMessageHash [as verifyWithMessageHash] (jsrsasign-4.7.0/npm/lib/jsrsasign.js:251:3675)
at verify (jsrsasign-4.7.0/npm/lib/jsrsasign.js:230:10483)
at main.js:43:24
如果你以前有做这件事的经验,我将感谢你的帮助。感谢
以下是如何做到的:
var KJUR = require("cloud/jsrsasign.js");
var publicKey =
"-----BEGIN PUBLIC KEY-----n" +
// your public key from google play
"-----END PUBLIC KEY-----n";
var verifier = new KJUR.crypto.Signature({alg: "SHA1withRSA"});
verifier.init(publicKey);
verifier.updateString(signedData); // signedData from IAB response
var result = verifier.verify(KJUR.b64utohex(signature));
请确保将签名从base64转换为十六进制。
我猜随着jsrasign的更新,情况发生了一些变化——我的解决方案如下:
cloud/lib/crypto.js:
// jsrasign expects to be running in a browser and expects these to be in the global namespace
var navigator = {},
window = {};
// Include contents of jsrsasign-latest-all-min.js from https://kjur.github.io/jsrsasign/
// ------------- Snip -------------
// Expose a Validate method
exports.Validate = function(sText, sPublicKey, sSignature) {
var cVerifier = new KJUR.crypto.Signature({ alg: 'SHA1withRSA' });
cVerifier.init("-----BEGIN PUBLIC KEY-----n" + sPublicKey + "-----END PUBLIC KEY-----n");
cVerifier.updateString(sText);
return cVerifier.verify(b64utohex(sSignature));
};
cloud/MakePurchase.js:
var Crypto = require('cloud/lib/crypto'),
// You should have got this from https://play.google.com/apps/publish
sPublicKey = 'SomethingSlightlySecretUsing64CharactersWithNoSpacesOrNewLines';
// Assume you have done something to get back a Google receipt object containing:
// json: A stringified JSON object with the purchase details
// signature: A base64 string
// payload: Data you might have set when you made the purchase
if (Crypto.Validate(cReceipt.json, sPublicKey, cReceipt.signature)) {
// Purchase confirmed
}