0

在苹果 SKADNetwork 之后,我使用此命令生成了私钥和公钥

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

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

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

但是当我尝试通过 c# 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, 0, 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 核心 3 测试

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


            string pars = getParamsSignature("2.0", "xxxxx.skadnetwork", "10", "302584613", "0a97ad57-87d1-49e7-b166-9152c708251b", "1613749507007", "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)
            {
            }
4

0 回答 0