c# - 如何使用 c# 验证安装验证回发 SKAdnetwork?
问题描述
按照文档完成此操作所需的: https ://developer.apple.com/documentation/storekit/skadnetwork/verifying_an_install_validation_postback
根据您从参数创建的 UTF-8 字符串验证来自 attribution-signature 参数的 Apple 签名值。使用 Apple 的公钥和使用椭圆曲线数字签名算法 (ECDSA) 的 SHA256 哈希。
在我们的回发中,我们收到了这个测试 Json:
{
"version" : "2.0",
"ad-network-id" : "com.example",
"campaign-id" : 42,
"transaction-id" : "6aafb7a5-0170-41b5-bbe4-fe71dedf1e28",
"app-id" : 525463029,
"attribution-signature" : "MDYCGQCsQ4y8d4BlYU9b8Qb9BPWPi+ixk\/OiRysCGQDZZ8fpJnuqs9my8iSQVbJO\/oU1AXUROYU="
"redownload": 1,
"source-app-id": 1234567891
"conversion-value": 20
}
苹果提供了这个公钥:
MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEMyHD625uvsmGq4C43cQ9BnfN2xslVT5V1nOmAMP6qaRRUll3PB1JYmgSm+62sosG
我们正在尝试验证签名,但仍有异常:System.Security.Cryptography.CryptographicException: 'The parameter is wrong"。
static void Main(string[] args)
{
string publickey = "MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEMyHD625uvsmGq4C43cQ9BnfN2xslVT5V1nOmAMP6qaRRUll3PB1JYmgSm+62sosG";
var attribution_signature = "MDYCGQCsQ4y8d4BlYU9b8Qb9BPWPi+ixk/OiRysCGQDZZ8fpJnuqs9my8iSQVbJO/oU1AXUROYU=";
string pars = getParamsSignature("2.0", "com.example", "42", "525463029", "6aafb7a5-0170-41b5-bbe4-fe71dedf1e28", "1", "1234567891");
VerifySignature(publickey, attribution_signature, pars);
}
// https://stackoverflow.com/questions/59078889/ecdsa-verify-signature-in-c-sharp-using-public-key-and-signature-from-java
//0x30|b1|0x02|b2|r|0x02|b3|s
// b1 = Length of remaining data
// b2 = Length of r
//b3 = Length of s
static void VerifySignature(string publicKey, string signature, string paramss)
{
byte[] publicKeyBytes = Convert.FromBase64String(publicKey);
var signatureBytes = Convert.FromBase64String(signature); //30 49 30 13 06072a8648ce3d020106082a8648ce3d030101 03 32 00043321c3eb6e6ebec986ab80b8ddc43d0677cddb1b25553e55d673a600c3faa9a4515259773c1d496268129beeb6b28b06
var data = Encoding.UTF8.GetBytes(paramss);
var key = asn1_to_rs(publicKeyBytes);// "06072a8648ce3d020106082a8648ce3d03010100043321c3eb6e6ebec986ab80b8ddc43d0677cddb1b25553e55d673a600c3faa9a4515259773c1d496268129beeb6b28b06";
CngKey cngKey = CngKey.Import(key, CngKeyBlobFormat.EccPublicBlob);
ECDsaCng eCDsaCng = new ECDsaCng(cngKey);
bool result = eCDsaCng.VerifyData(data, signatureBytes);
}
static byte[] asn1_to_rs(byte[] asn)
{
var b1 = asn[1];
var b2 = asn[3]; // b2 = Length of r
var r = asn.Skip(4).Take(b2);
var b3 = asn[r.Count()];
var s = asn.Skip(4 + b2 + 4).Take(b3);
return r.Concat(s).ToArray();
}
static string getParamsSignature(string version, string ad_network_id, string campaign_id, string app_id, string transaction_id, string redownload, string source_app_id)
{
return (version + '\u2063' + ad_network_id + '\u2063' + campaign_id + '\u2063' + app_id + '\u2063' + transaction_id + '\u2063' + redownload + '\u2063' + source_app_id);
}
解决方案
Apple 表示将“1”替换为“true”作为重新下载值。
redownload 注意:使用字符串“true”或“false”表示redownload参数的布尔值。
推荐阅读
- c++ - 指向访问其 () 运算符的类的指针的 decltype
- python - tkinter:无需按下按钮即可输入条目并生成结果
- c - C语言如何将char文字转换为数字,反之亦然
- vue.js - Vuetify:仅样式化 v-data-table 的最后一行
- java - Mybatis 问题 - 通过 MyObjectFactory 将参数传递给我的 TypeHandler 类
- google-sheets - 谷歌表格 - 查找包含特定文本的单元格
- amazon-web-services - 无法在 AWS datalake/glue UI 中查看表
- html - 在 CSS 中选择同一类的特定元素
- angular - 不同实例的相同组件之间的角度组件交互
- reactjs - React Metronic 主题项目运行报错