如何在进行InApp结算时保护Google Play公钥

2022-09-01 01:56:14

实际上,关于保护公钥有点愚蠢(那么公钥的定义是什么?),但根据Google的文档

为了保护您的公钥免受恶意用户和黑客的攻击,请不要将其作为文本字符串嵌入到任何代码中。相反,请在运行时从片段构造字符串或使用位操作(例如,带有其他字符串的XOR)来隐藏实际的键。密钥本身不是机密信息,但您不希望黑客或恶意用户容易用另一个密钥替换公钥。

有什么推荐的方法吗?

我知道有很多方法可以做到这一点,我只是不想遵循过去人们处理密码哈希的相同方式(例如md5,sha1等),我想知道上述用例中的最佳实践。


答案 1

这在这里出现了很多:)您引用的段落背后的想法是,为了使应用内计费安全,您需要验证交易签名。这些帐户使用与您的开发人员帐户关联的私钥进行签名。密钥驻留在Google的服务器上,因此可以相当安全地假设没有其他人可以使用它签署数据。要验证它,您需要从开发人员控制台复制公钥。如果有人在你的应用中替换了它,他们可能会欺骗它接受来自未经授权来源的应用内计费交易,因为如果他们植入公钥,他们可能还会控制相应的私钥。然而,在实践中,简单地在正确的位置修改代码以始终返回 true for 或您可能拥有的类似方法要容易得多,而没有人这样做。isLicensed()hasItem()

当然,保护密钥的最佳方法是根本不将密钥放在应用中。将所有事务验证逻辑移动到服务器,并使用 HTTPS 连接到它。正确验证证书链,以确保您正在与自己的服务器通信。否则,有人可能会弄乱DNS并欺骗您的应用程序连接到他们自己的服务器。几周前,针对iOS购买的类似攻击被宣布。

接下来最好的办法是以某种方式混淆密钥,并将其包含在你的应用中。这样做的好处是你不需要服务器,但缺点是,如果有人足够坚定,他们会弄清楚,因为他们总是可以反转你的应用程序的字节码。所以你最好的选择是想出你自己的原创方法来做到这一点,而不是出现在公共论坛上:)为了使它更难一些,您可以在本机代码中实现验证部分,这更难(但并非不可能)分析。尽管如此,如上所述,在正确的位置修补字节码比尝试替换公钥要容易得多,所以这是大多数破解者会做的事情。


答案 2

至少执行简单的文本转换。这个想法是,普通的dex反汇编不会泄露你的公钥。

下面是进行简单字符串编码/解码的函数示例:

/**
 * Simple String transformation by XOR-ing all characters by value.
 */
static String stringTransform(String s, int i) {
   char[] chars = s.toCharArray();
   for(int j = 0; j<chars.length; j++)
      chars[j] = (char)(chars[j] ^ i);
   return String.valueOf(chars);
}

然后,您的私钥作为编码字符串存储在源中(使用此函数对其进行编码),并在运行时使用相同的函数进行解码。这是谷歌提出的“异或”方法。

您自己创建“i”参数,任何随机的参数(例如0x27或其他参数)都可以工作。如果以这种方式隐藏更多字符串,请对每个转换使用不同的“i”。


推荐