Android应用程序中防止秘密密钥被黑客攻击的解决方案是什么?

9
我需要在应用程序内存储一个私有字符串密钥。它的值永远不会改变,并且是手动在代码中设置的。显然,我不能将其存储为String,因为即使应用混淆后,反向工程方法也能够揭示它。
你建议如何保护这个私有密钥?
我考虑将它保存到数据库中,但数据库也可以从手机中提取出来。
PS. 这个密钥是一个特殊参数,是一个重要方法的关键,它对任何人都必须保密!它不是解密密钥。这个字符串将被用作加密方法(md5或类似方法)的参数,然后将结果发送到我们的互联网服务。
编辑
抱歉,让问题变得如此复杂。我认为我可以尽可能少地提供信息得到答案。
这个应用程序将允许用户向互联网服务发送一些文本,然后该文本将被发布到网站上。我们需要确保文本通过Android手机发送,因为任何网络机器人脚本都可以模仿Android手机并发布垃圾邮件。由于移动电话不支持类似验证码的方法,因此将使用一个秘密密钥,将其通过md5(以及其他一些内容)进行处理以生成哈希码。这个哈希码将被发送到一个互联网服务。该互联网服务将使用相同的密钥获取md5结果,然后进行比较以确定发送者是移动电话还是机器人。
这真的是我可以说的最多的了。我希望这足够了解。

7
“it's crucial it stays unknown to anyone” 的意思是“它必须对任何人保密”。如果真的非常关键,就根本不能在应用程序中包含它。否则,攻击者可以使用调试器逐步执行代码,在代码使用该字符串的位置停止,并检查其内容。攻击者不需要知道如何解密该字符串,只需安装 Android 开发工具即可让您的代码执行解密操作。 - Adam Mihalcin
@AdamMihalcin 不,这个字符串将被用于加密,然后将结果发送给其他互联网服务。这会改变什么吗? - sandalone
我同意,如果您像密码/TAN或类似的方式使用字符串,您可能需要研究一下银行现在的做法,即向手机发送一次性代码并仅使用此代码-每当用户想要访问时,他都会获得一个新的代码。@Adam Mihalcin,您到底是什么意思?我明白人们可以查看代码,但是调试已加载的应用程序,这怎么可能呢? - user387184
@AdamMihalcin 再次编辑了答案。 - sandalone
@user387184 再次编辑了答案。 - sandalone
请查看我在类似问题上的回答:在混淆代码中隐藏字符串 - Efra Espada
2个回答

11

我建议您重新考虑您的安全架构。任何随应用程序一起发送的内容都是可以被发现的。(例如,Android的许可验证库是设计成与应用程序一起发送公钥的。)

其中一个可能性是应用程序从服务器检索密钥(通过安全套接字或https连接)。这显然需要应用程序提交给服务器某种身份验证/验证(可能基于用户输入)。

如果您正在使用密钥进行加密,那么请再次查看公钥加密的工作原理。您的应用程序应该有公钥;互联网服务可以使用匹配的私钥进行解密。


嗨,Ted,我已经编辑了这个问题。 "这个字符串将被用作加密方法(md5或类似方法)的参数,然后将结果发送到我们的互联网服务。" - sandalone
2
@sandalone - 看起来你应该从服务器获取哈希密钥。用户可以通过手机输入凭据,以便服务器在发放密钥之前进行验证。你可以对此进行精细处理:哈希密钥可以基于手机生成的随机数,并与凭据一起提交。 - Ted Hopp
是的,我根据您的建议想出了类似的解决方案。谢谢! - sandalone

4
如果您能接受@Adam的评论,我至少知道一种解决方案,可以以一种... 持久的方式在手机上保存字符串值,这意味着该值将在卸载/重新安装应用程序时保留(但恢复出厂设置将删除它),但对用户而言仍处于“隐藏”状态(即存储在系统私有存储中,而不是SD卡上)。
您可以使用系统设置内容提供程序来存储该值,如下所示:
final String myKey = "verySecretKey";
final String myValue = "verySecretValue";
final boolean isSuccess = System.putString(getContentResolver(), myKey, myValue);

要检索它,您可以执行以下操作:

myValue = System.getString(getContentResolver(), myKey);

是的,在已获取root权限的手机上,一个熟练的用户可能会得到持久化值,但在这种情况下,没有什么是神圣的了,@Adam的评论将变得有效:不应该将数据存储在设备上。


这真的有效吗?它似乎是一种hack,而且Android不会允许这样做(或者在未来的版本中可能会破坏)。Settings.System是用于...系统设置,而不是应用程序个人存储。 - Tom
是的,它有效,并且我也期望它有效,特别是因为有一个公开记录的API。此外,检查文档(http://developer.android.com/reference/android/provider/Settings.System.html),可以注意到`putString`方法似乎已启用“通用键值存储”,而其他`put...`方法似乎主要用于修改现有键(但这可能是一种解释问题)。 - dbm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接