SSV Callback (Server-Side Verification)
来自服务器的 SSV 回调验证过程
在向 SSV 回调服务器注册时,服务器会以如下形式发送数据。
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==
此时从 query 中将 signature 与其余部分分离
由 AD(X) 提供的 公钥获取 key 列表。
在 key 列表中获取与 query 中 keyid 相同的 keyid 所对应的 public key。
使用该 public key ECDSA并用支持该算法的库对 signature 进行验证。
此过程与 AdMob SSV 服务器验证相似。
请参考下面的 Java Security 或 Tink 库代码示例进行操作。
1) 使用 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) 使用 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());
}
}最后更新于
这有帮助吗?