TheCarpetMerchant
How do I use crypto.subtle.importKey to verify the signature sent by Admob SSV ?
Thanks ! "spki" was what was wrong in my setup. I can create the key, but the verification fails.
´´´
async function verify(queryUrl: string) {
const {signature, key_id} = queryString.parse(queryUrl);
let queryParamsString = queryUrl;
if (queryParamsString.indexOf('?') > -1) {
queryParamsString = queryUrl.split('?')[1];
}
const contentToVerify = queryParamsString.substring(0, queryParamsString.indexOf('signature') -1);
const googleKeyRes = await axios.get('https://gstatic.com/admob/reward/verifier-keys.json');
const {keys} = googleKeyRes.data;
const base64Decoded = base64.decodeBase64(keys.find((e) => e['keyId'] == key_id).base64);
const key = await crypto.subtle.importKey('spki', base64Decoded, {name: "ECDSA", namedCurve: 'P-256'}, true, ["verify"]);
const encoder = new TextEncoder()
const s = encoder.encode(signature); // "MEQCIG8sJ33C2t7D-0PeLIbO2rxH7c78MS3G3P8-b_KBuQCUAiBUhq06AFVfpDTr8XPaBtSsAGUNZAQysKuJiVuly90g8A"
const d = encoder.encode(contentToVerify); // "ad_network=5450213213286189855&ad_unit=1234567890&reward_amount=1&reward_item=Reward×tamp=1718045362304&transaction_id=123456789&user_id=1"
const result = await crypto.subtle.verify({name: "ECDSA", hash: "SHA-256"}, key, s, d);
if (result) {
return true;
} else {
throw new Error('Invalid Signature Supplied');
}
};
´´´
This is according to https://developers.google.com/admob/android/ssv, which says to have the query content ("ad_network=" etc) as the content that's signed.
I'm probably doing the encoding wrong I guess but I can't figure out what's wrong about it. It defaults to UTF8, from what I read and the admob doc uses UTF8 as well.
4 replies