在 c# .net 中为 SKAdnetwork 生成签名广告

问题描述

关注苹果SKADNetwork 我用这个命令生成了私钥和公钥

openssl ecparam -name prime192v1 -genkey -noout -out private_key.pem

openssl ec -in private_key.pem -pubout -out public_key.pem

我能够在这个项目之后用 python 生成一个有效的签名 https://github.com/singular-labs/Singular-SKAdNetwork-App/tree/master/skadnetwork-server

但是当我尝试通过 c# bouncycastle 库生成签名时,如果我使用相同的数据,我会得到不同的结果。

BOUNCYCASTLE 测试

 public static asymmetricCipherKeyPair ReadasymmetricPrivateKeyParameter(string pemFilename)
    {
        var fileStream = System.IO.File.OpenText(pemFilename);
        var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(fileStream);
        var KeyParameter = (asymmetricCipherKeyPair)pemReader.Readobject();
        return (asymmetricCipherKeyPair)KeyParameter;
    }

    static void Main(string[] args)
    {
        asymmetricCipherKeyPair pkey = ReadasymmetricPrivateKeyParameter("private_key.pem");

        string pars = getParamsSignature("2.0","xxxxxxx.skadnetwork","10","302584613","0a97ad57-87d1-49e7-b166-9152c708251b","1613749507007","0");

        Sign(pkey,"",pars);
        Console.Read();
    }

    static string getParamsSignature(string version,string ad_network_id,string campaign_id,string target_app_id,string nonce,string timestamp,string source_app_id)
    {
        string[] p = new string[] {
        version,ad_network_id,campaign_id,target_app_id,nonce,source_app_id,timestamp
        };
        return string.Join("\u2063",p);
    }

    public static bool Sign(asymmetricCipherKeyPair pubKey,string msg)
    {
        try
        {

            ECDomainParameters aa;
            byte[] msgBytes = Encoding.UTF8.GetBytes(msg);

            ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");

            signer.Init(true,pubKey.Private);

            signer.BlockUpdate(msgBytes,msgBytes.Length);

            byte[] sigBsdytes = signer.GenerateSignature();

           
            var signature = Convert.ToBase64String(sigBsdytes);



            //MDUCGQDgqw1YQN/vvHTxXXTpovNYUnACzkFrXJwCGCXAnr3TUbbqIUr6cBamymrypcQET5RR7Q==


        }
        catch (Exception exc)
        {
            Console.WriteLine("Verification Failed with the error: " + exc.ToString());
            return false;
        }
        return false;
    }

.NET CORE 3 测试

static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");


            string pars = getParamsSignature("2.0","xxxxx.skadnetwork","0");

            //bool aaaaa = VerifySignature(aa,attribution_signature,pars);
            string eccPem = File.ReadAllText("private_key.pem");


            var key = ECDsa.Create(ECCurve.CreateFromValue("1.2.840.10045.3.1.1"));
            key.ImportECPrivateKey(Convert.FromBase64String(eccPem),out _);
         
            var signed = key.SignData(Encoding.UTF8.GetBytes(pars),HashAlgorithmName.SHA256);
            var hash = Convert.ToBase64String(signed);

        }

使用 .net.core 测试结果更糟,因为每次执行时令牌都会发生变化。我认为这是一种随机行为。

#BOUNCYCASTLE 确定性测试格式 R|S 和 ASN1

            byte[] msgBytes = Encoding.UTF8.GetBytes(msg);


            ECDsaSigner signer = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest()));
            signer.Init(true,pubKey.Private);
            var sigBsdytes = signer.GenerateSignature(msgBytes);


            //SIGNATURE (R|S)
            Console.WriteLine( Convert.ToBase64String(sigBsdytes.SelectMany(a => a.ToByteArray()).ToArray()));


            //SIGNATURE (ASN1)
            var s = new MemoryStream();
            try
            {
                DerSequenceGenerator seq = new DerSequenceGenerator(s);

                seq.Addobject(new DerInteger(sigBsdytes[0]));
                seq.Addobject(new DerInteger(sigBsdytes[1]));
                seq.Close();

                
                var signature = Convert.ToBase64String(s.ToArray());

                Console.WriteLine(signature);
            }
            catch (IOException e)
            {
            }

如果输入的字符串相同,仍然会得到与 python FastECDSA 库不同的结果。

更新解决方案:感谢@topaco 评论

            var crypt = new System.Security.Cryptography.SHA256Managed();
            byte[] msgBytes = crypt.ComputeHash(Encoding.UTF8.GetBytes(msg));

            ECDsaSigner signer = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest()));
            signer.Init(true,pubKey.Private);
            var sigBsdytes = signer.GenerateSignature(msgBytes);

            //SIGNATURE (ASN1)
            var s = new MemoryStream();
            try
            {
                DerSequenceGenerator seq = new DerSequenceGenerator(s);

                seq.Addobject(new DerInteger(sigBsdytes[0]));
                seq.Addobject(new DerInteger(sigBsdytes[1]));
                seq.Close();


                var signature = Convert.ToBase64String(s.ToArray());

                Console.WriteLine(signature);
            }
            catch (IOException e)
            {
            }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)