SSV Callback (Server-Side Verification)
SSV Callback Verification
When registering a server for SSV callbacks, the server will receive data in the following format.
https://callback_url?adnetwork=sampleadnetwork&adunit=sampleAdUnitID&customdata=sampleCustomData&keyid=62031534a8bbd887dcca3d05&rewardamount=5×tamp=1698114496119094000&transactionid=119065000_sampleAdUnitID_sampleMediationID&userid=sampleUserID&signature=MIGIAkIA4Urg1Hs7p9hLbZ-SLUemeluocwENpbiwxVmhEw9KtVGEcH6d7dRmIyAENHcTPDcPeJP_YVAG9YO6K3cw24jUpD0CQgEZKN68mjOytwG1-H4VgYs3QXRWOBHx3D3bqYaWJvQwQ52X-OxsIDcxSuDo_FyC1m2c7fxV7ybgNKLFmUuo7zN2qA==
Separate the signature from the rest of the query.
Retrieve the list of keys using the public key provided by AD(X).
From the key list, obtain the public key that has the same key id as the one in the query.
Verify the signature using this public key with a library that supports ECDSA.
This process is similar to AdMob’s server-side SSV verification.
Please refer to the sample code using Java Security or Tink Library below for implementation
1) Using Java Security
import java.security.*;
public void verifyUsingJavaSecurityPackage() {
String publicKeyBase64 = "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAfu3ar6/tvJwXvDDIl9pfU0lPomGC6rxi37zbc6SYDl4bo7CRhm/sx/0hjitWXCRZddlv7b6O301PR/SZ9WVHpmgAcWeBxfAmEk7t4tyo1qStUYOApy4VZLaVsAnqklLhaM9qZp+79ck2UMxxD/QkClrTlxR+b/Sz42tD+Tv7YbvNZZs=";
String signatureBase64 = "MIGIAkIA4Urg1Hs7p9hLbZ-SLUemeluocwENpbiwxVmhEw9KtVGEcH6d7dRmIyAENHcTPDcPeJP_YVAG9YO6K3cw24jUpD0CQgEZKN68mjOytwG1-H4VgYs3QXRWOBHx3D3bqYaWJvQwQ52X-OxsIDcxSuDo_FyC1m2c7fxV7ybgNKLFmUuo7zN2qA==";
String dataToVerify = "adnetwork=sampleadnetwork&adunit=sampleAdUnitID&customdata=sampleCustomData&keyid=62031534a8bbd887dcca3d05&rewardamount=5×tamp=1698114496119094000&transactionid=119065000_sampleAdUnitID_sampleMediationID&userid=sampleUserID";
try {
// Create a public key from the encoded bytes
KeyFactory keyFactory = KeyFactory.getInstance("EC");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBase64));
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
// Initialize the Signature object for ECDSA
Signature ecdsa = Signature.getInstance("SHA256withECDSA");
ecdsa.initVerify(publicKey);
// Update the Signature object with the data
ecdsa.update(dataToVerify.getBytes("UTF-8"));
// Verify the signature
boolean isVerified = ecdsa.verify(Base64.getUrlDecoder().decode(signatureBase64));
if (isVerified) {
System.out.println("Signature is verified.");
} else {
System.out.println("Signature verification failed.");
}
} catch (Exception e) {
System.out.println("e:" + e.toString());
}
}
2) Using Tink Library
public void verifyUsingGoogleTinkLibrary() {
String publicKeyBase64 = "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAfu3ar6/tvJwXvDDIl9pfU0lPomGC6rxi37zbc6SYDl4bo7CRhm/sx/0hjitWXCRZddlv7b6O301PR/SZ9WVHpmgAcWeBxfAmEk7t4tyo1qStUYOApy4VZLaVsAnqklLhaM9qZp+79ck2UMxxD/QkClrTlxR+b/Sz42tD+Tv7YbvNZZs=";
String signatureBase64 = "MIGIAkIA4Urg1Hs7p9hLbZ-SLUemeluocwENpbiwxVmhEw9KtVGEcH6d7dRmIyAENHcTPDcPeJP_YVAG9YO6K3cw24jUpD0CQgEZKN68mjOytwG1-H4VgYs3QXRWOBHx3D3bqYaWJvQwQ52X-OxsIDcxSuDo_FyC1m2c7fxV7ybgNKLFmUuo7zN2qA==";
String dataToVerify = "adnetwork=sampleadnetwork&adunit=sampleAdUnitID&customdata=sampleCustomData&keyid=62031534a8bbd887dcca3d05&rewardamount=5×tamp=1698114496119094000&transactionid=119065000_sampleAdUnitID_sampleMediationID&userid=sampleUserID";
try {
ECPublicKey publicKey = EllipticCurves.getEcPublicKey(Base64.getDecoder().decode(publicKeyBase64));
EcdsaVerifyJce verifier = new EcdsaVerifyJce(publicKey, Enums.HashType.SHA256, EllipticCurves.EcdsaEncoding.DER);
verifier.verify(Base64.getUrlDecoder().decode(signatureBase64), dataToVerify.getBytes("UTF-8"));
} catch (Exception e) {
System.out.println("e:" + e.toString());
}
}
Last updated
Was this helpful?