3

在我们的应用程序中,我们有一个应用程序内购买。客户端向 google play 请求购买,并将从 google play 收到的所有信息(收据、nonce、订单等和签名)发送到用 c# 编写的服务器进行验证。我正在使用这篇文章中的代码示例

问题是验证失败。

注意:客户端以 JSon 格式发送所有数据,为此我们操作从 google play 返回的字符串,如下所示:

在客户端

data = data.replace("\"", "\\\"");

在服务器端

data = data.Replace("\\", "");

编辑:JSON 代码示例,从 App 到服务器

{
    "data": "{\\\"nonce\\\":3768004882572571381,\\\"orders\\\":[{\\\"notificationId\\\":\\\"android.test.purchased\\\",\\\"packageName\\\":\\\"com.company.appname\\\",\\\"orderId\\\":\\\"transactionId.android.test.purchased\\\",\\\"purchaseState\\\":0,\\\"productId\\\":\\\"android.test.purchased\\\",\\\"purchaseTime\\\":1335790350398}]}",
    "signature": "ML6ocr89x3+oT3ZKnQBEE2mNEVj6LHwt+L4I/bnhl+xCpJcjhsAIhfAumeCKwXonJV4Oh9n3Sa7SVT0F7S9XcgE2xGcf2zOZmxHB1wQcyM7fQiGj39Cyb2zuYf3T6Cs1eerDzHaO1teVQZyIhBPJf4cszD/WikSpHcF8zBTvV58FkRVwl2NR4CEvI2FrKFek8Xq2O4CsclCpS5UJorMKRAer9pcSD1BkFzynQJffbaDcRLFZ7i9vABV+GZ/xWxMGPuYYE77GYk8Q2fejgmwiZ3ysY0VjEfGRCpSA==",
    "userId": 1
}

编辑:该测试失败。验证是一个布尔变量,应该是真的

using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                RSAParameters rsaKeyInfo = new RSAParameters()
                {
                    Exponent = Convert.FromBase64String(ConfigurationManager.AppSettings["RsaKeyInfo.Exponent"]),
                    Modulus = Convert.FromBase64String(ConfigurationManager.AppSettings["RsaKeyInfo.Modulus"])
                };
                rsa.ImportParameters(rsaKeyInfo);
                verified = rsa.VerifyData(Encoding.ASCII.GetBytes(data), "SHA1", Convert.FromBase64String(signature));
            }
4

1 回答 1

2

问题是客户端将从谷歌收到的 JSON 字符串转换为 JSONObject,然后将其转换回 toString()。这导致一些 json 项在字符串中的位置发生变化,从而为签名创建了不同的字节对象,但失败了。

例如 - 这是从谷歌收到的 JSON:

{
    "nonce": 1165723044405495300,
    "orders": [
        {
            "notificationId": "android.test.purchased",
            "orderId": "transactionId.android.test.purchased",
            "packageName": "com.company.appname",
            "productId": "android.test.purchased",
            "purchaseTime": 1335874740360,
            "purchaseState": 0
        }
    ]
}

如果您将其操作为 JSONObject ( new JSONObject(json)),然后返回到字符串 ( json.toString()),则可能会导致某些 json 项目的位置发生变化,例如(请注意 orderId 不再是订单数组中的第二个):

{
        "nonce": 1165723044405495300,
        "orders": [
            {
                "notificationId": "android.test.purchased",
                "packageName": "com.company.appname",
                "productId": "android.test.purchased",
                "purchaseTime": 1335874740360,
                "orderId": "transactionId.android.test.purchased",
                "purchaseState": 0
            }
        ]
    }

GetBytes(data) 不返回相同的结果,因此验证失败。

解决方案当然是避免操纵从google接收到的json字符串。只需将其放入您正在构建的 JSONObject 中即可。jsonObj.put(“数据”,jsonStringFromGoogle)。

于 2012-05-01T12:32:23.933 回答