我有一个 Android 应用程序需要经常连接到服务器以检索或添加数据库敏感数据。我需要验证对服务器的调用是从应用程序发出的,所以我使用了这种方法:how to verify the identity of the client from the server?它包含在服务器中验证的应用程序中的硬编码字符串 key 。 但后来我意识到有像 dex2jar 这样的工具,它会泄露我的所有代码(即使混淆了混淆器),尤其是这个硬编码 key 。
有没有更优雅、更安全的方法来验证服务器调用是从我的应用发出的?
PS:很抱歉英语不好,显然我不是母语人士。
最佳答案
如果只有您的客户端和服务器,您可以(并且应该)使用相互验证的 SSL 而无需购买任何东西。您控制着服务器和客户端,因此每个人都应该只信任一个属于另一个的证书,您不需要为此目的使用 CA。
这是高级方法。创建自签名服务器 SSL 证书并部署在您的 Web 服务器上。为此,您可以使用 Android SDK 中包含的 keytool。然后创建一个自签名客户端并将其部署在您的应用程序中作为资源包含在您的应用程序中的自定义 keystore 中(keytool 也会生成它)。将服务器配置为需要客户端 SSL 身份验证并且只接受您生成的客户端证书。将客户端配置为使用该客户端证书来标识自己,并且只接受您在服务器上为该部分安装的一个服务器端证书。
对此的分步回答比此处保证的要长得多。我建议分阶段执行此操作,因为网络上有关于如何在服务器端和客户端处理 Android 中的自签名 SSL 证书的资源。我在 O'Reilly 出版的《Android 平台的应用程序安全性》一书中也有完整的演练。
您通常会将证书/私钥存储在某种类型的 keystore 中(如果您使用的是 Android,则为 KeyStore)并且该 keystore 将被加密。该加密基于密码,因此您需要 (1) 将该密码存储在客户端的某个位置,或者 (2) 在用户启动您的客户端应用程序时询问用户密码。您需要做什么取决于您的用例。如果 (2) 是可接受的,那么您已经保护了您的凭据免受逆向工程,因为它将被加密并且密码不会存储在任何地方(但用户每次都需要输入)。如果您执行 (1),那么有人将能够对您的客户端进行逆向工程,获取密码,获取 keystore ,解密私钥和证书,并创建另一个能够连接到服务器的客户端。
您无法阻止这种情况发生;您可以使代码的逆向工程变得更加困难(通过混淆等),但您不能让它变得不可能。您需要确定您尝试使用这些方法减轻的风险是什么,以及为减轻风险值得做多少工作。
关于php - 如何验证服务器调用是从应用程序发出的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10155316/