【问题标题】:which is the safest way to include a pair of key (public/private) in a apk这是在 apk 中包含一对密钥(公钥/私钥)的最安全方法
【发布时间】:2012-02-07 15:35:54
【问题描述】:

我正在为 android 开发一个应用程序,我必须通过一对私钥和公钥保持与服务器的安全通信。在我的 apk 中存储私钥的最安全方法是什么?显然我会混淆代码,但我想要更多的安全性。我想到了以下选项:

如果我用签署交易信息的方法创建一个本地共享库,apk 只需要包含 .so 文件,而且这个文件是机器码,所以反编译可能很困难,不是吗?

有什么想法吗? 谢谢

【问题讨论】:

  • 谁是您的威胁模型中的攻击者?您设备的合法用户?
  • 攻击者不会是用户,问题是应用程序将访问支付服务,我们想要一个安全的应用程序。在一个简单的 apk 中,任何人都可以反编译,获取密钥并使用它们访问支付系统
  • 您应该设计您的应用程序,使拥有应用程序完整源代码和所有嵌入式密钥的用户不会做任何坏事。

标签: android security apk


【解决方案1】:

将密钥对存储在 keystore 中,并将密钥库作为资源包含在您的 APK 中。 Android 倾向于使用 BouncyCastle Key Store (BKS) 格式。密钥库专为此目的而设计。

请注意,您应该使用密码保护密钥库,并且您的应用程序需要知道该密码才能访问密钥库。因此,您需要向用户询问密码才能访问密钥库或在代码中包含密码(对其进行混淆以使攻击者更难进行逆向工程)。如果有人要对您的应用程序进行逆向工程以恢复您的加密密钥库和访问它所需的密码,那么在已编译的本机库中包含该密码不会带来太多额外的障碍。

但是,您可能不需要这样做。如果您的目标是保护/加密传输到/从服务器传输的数据,请使用 SSL/TLS。如果您不进行客户端身份验证,则您的服务器需要 SSL 证书,但您的客户端不需要;该协议负责以安全的方式为您生成加密密钥。如果您确实希望服务器对客户端进行身份验证(使您的服务器只与您的客户端对话),您需要在您的应用程序中安装客户端 SSL 证书......这是您的私钥大概在想。

我还会将您指向Application Security for the Android Platform。这本书(免责声明:我写了这本书)有一整章讨论了如何设计安全的 Android 应用程序到服务器的通信,并附有代码示例来说明如何实施适当的保护。你可能想读一读。

【讨论】:

  • 您的回复开启了解决问题的不同方法。尽管进行了混淆,但我认为密钥库的密码在代码中仍然可见,因此访问密钥库并不难。
  • 确实如此。然而……这是最好的。如果您在设备上运行的客户端应用程序需要访问它存储的内容,那么有权访问该设备的人也将能够访问它。你所能做的一切都会让它变得更加困难。当然,您不能存储密码并在每次需要访问密钥时强制用户输入密码。不是一个理想的用户体验,但密码必须来自某个地方。
  • 这是一件大事!我需要保护客户端证书。该应用程序用于购买,客户端(使用该应用程序的任何人)和服务器之间的所有交易都必须签名。恐怕任何人都可以提取证书并开始向服务器发送有效交易。
  • 然后,您需要在每笔交易中向用户询问密钥库的密码。您需要设计您的应用程序/系统,假设您的应用程序 APK 中包含的任何内容都可以被想要花费时间/精力的人恢复。因为这个假设是正确的。
  • 如何从扫描的二维码中获取密钥库的密码,该二维码通过“像银行一样”发送给用户,或者在用户注册时在 SSL 下显示在您的服务器上。每次安装应用程序时您只能执行一次此操作,并且更加用户友好。想想 Google 授权 Google Glass 访问您的帐户的方式。
【解决方案2】:

首先,为了在您的客户端应用程序和服务器之间实现安全通信,从概念上讲,您只需要服务器的公钥。这允许您与服务器建立单向信任关系并建立安全会话,其中服务器的身份得到保证。

虽然上述方法当然不能提供双向信任(客户端无法识别到服务器),但在大多数应用程序中建立通信通道时,这种信任级别并不是真正需要的。

如果您的要求是使用公钥/私钥向服务器提供客户端身份验证,那么事情会变得更加复杂,因为如果您将密钥放在 apk 中,无论您对其进行了多少混淆(包括将其嵌入到本机库中)它只会减慢专门的恶意用户。

在客户端存储私钥的唯一方法是对其进行加密。但是你有一个类似的问题,即在哪里存储解密密钥。最简单的解决方案是为客户端应用程序的用户生成一个公钥/私钥对,并要求用户提供一个对称加密/解密密钥(用户将始终必须输入)以在每次用户正在使用该应用程序。

替代方法是使用某种类似于智能卡的专用加密硬件设备,可以安全地存储私钥,但您仍然存在授权应用程序从设备读取密钥的问题(更不用说与所述设备接口的复杂性)。

现在,你必须问自己的问题是:“你试图阻止谁读取私钥?”(当然在回答了另一个问题之后:“做您确实需要客户端的公钥/私钥对”)。

【讨论】:

  • 服务器端强制的客户端公钥/私钥。我必须计算数据的哈希值,然后用私钥编码哈希值并将我的数据、哈希结果和公钥发送到服务器。这是我的主要问题,我该如何保护私钥! :)
  • @rdiaz82,在这种情况下,您很可能会为会话生成一个新的公钥/私钥。这样,私钥在运行时生成并为每个会话回收。除非服务器以某种方式需要提前注册客户端公钥的副本。
  • 这种情况下的私钥通常是生成用来识别应用程序用户的私钥,与用于加密对服务器响应的公钥不同。在这种情况下,密钥应在生成后存储在设备上,因为它是用户的密钥。
猜你喜欢
  • 2019-02-12
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 2013-08-06
  • 2018-07-19
  • 2018-02-27
  • 1970-01-01
  • 2017-12-02
相关资源
最近更新 更多