Skip to content

Instantly share code, notes, and snippets.

@evanhalley
Last active August 23, 2018 07:35
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save evanhalley/066e3a1cc2330d52deb2 to your computer and use it in GitHub Desktop.
Save evanhalley/066e3a1cc2330d52deb2 to your computer and use it in GitHub Desktop.
Using JavaScript / Node.js to do server side IAB signature verification
var crypto = require('crypto');
// the Base64 encoded Google Play license key / Base64-encoded RSA public key from the Google Play Dev Console
var publicKey = "ABCEDF1234....";
/** sample
{
"orderId":"12999763169054705758.1371079406387615",
"packageName":"com.example.app",
"productId":"exampleSku",
"purchaseTime":1345678900000,
"purchaseState":0,
"developerPayload":"bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ",
"purchaseToken":"opaque-token-up-to-1000-characters"
}
*/
// purchase data returned once the user has confirmed a purchase using IAB
var signedData = "'{.....}";
// signature that returned in the intent fired when a purchase is confirmed, INAPP_DATA_SIGNATURE
var signature = "12345ABCED...";
// use the mentioned pieces of information to determine whether or not the purchase is authentic
var wasVerified = verifyPurchase(publicKey, signedData, signature);
/**
* Verifies whether or the the signed data was signed by the private key
*/
function verifyPurchase(publicKey, signedData, signature) {
// let's decode the public key using some magic and sorcery
var decodedPublicKey = getPublicKey(publicKey);
// create the crypto verifier
var verifier = crypto.createVerify('SHA1');
// add the signed data
verifier.update(signedData);
// verify the data signature
return verifier.verify(decodedPublicKey, signature, 'base64');
}
function getPublicKey(publicKey) {
if (!publicKey) {
return null;
}
var key = chunkSplit(publicKey, 64, '\n');
var pkey = '-----BEGIN PUBLIC KEY-----\n' + key + '-----END PUBLIC KEY-----\n';
return pkey;
}
function chunkSplit(str, len, end) {
len = parseInt(len, 10) || 76;
if (len < 1) {
return false;
}
end = end || '\r\n';
return str.match(new RegExp('.{0,' + len + '}', 'g')).join(end);
}
@liu316484231
Copy link

Hi,Dude,i have a question is that the signedData is returned by the google android sdk,right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment