简体   繁体   English

这是在apk中包含一对密钥(公共/私有)的最安全方法

[英]which is the safest way to include a pair of key (public/private) in a apk

I'm developing an application for android and I have to maintain a secure communication with a server through a pair of private and public key. 我正在为Android开发应用程序,并且必须通过一对私钥和公钥与服务器保持安全通信。 Which is the safest way to storage the private key in my apk? 将私钥存储在我的apk中最安全的方法是什么? Obviously I'm going to obfuscate the code but I want more security. 显然,我将混淆代码,但我需要更高的安全性。 I have thought the following option: 我想到了以下选择:

If I create a native share library with the methods for sign the transaction information, The apk only have to contain the .so file and this file is in machine code, so the decompilation could be difficult, isn't it? 如果我使用用于签名交易信息的方法创建本机共享库,则apk仅必须包含.so文件,并且此文件位于机器代码中,因此反编译可能很困难,不是吗?

any ideas? 有任何想法吗? Thanks 谢谢

Store the keypair in a keystore and include the keystore as a resource in your APK. 将密钥对存储在密钥库中 ,并将密钥库作为资源包含在APK中。 Android tends to prefer the BouncyCastle Key Store (BKS) format. Android倾向于使用BouncyCastle密钥存储(BKS)格式。 Keystores are specifically designed for this purpose. 密钥库是专门为此目的而设计的。

Note that you should protect the keystore with a password and your application will need to know that password to access the keystore. 请注意,您应该使用密码保护密钥库,并且您的应用程序将需要知道该密码才能访问密钥库。 So, you're left with needing to ask the user for a password to access the keystore or include the password in your code (obfuscate it to make it harder for an attacker to reverse engineer). 因此,您只需要要求用户输入密码来访问密钥库或将密码包含在代码中即可(对密码进行混淆处理,使攻击者更难进行反向工程)。 If someone is going to the trouble of reverse engineering your application to recover your encrypted keystore and the password needed to access it, including that password in a compiled native library will not present much of an additional hurdle. 如果有人要对工程进行反向工程,以恢复您的加密密钥库和访问它所需的密码(包括已编译的本机库中的密码),则不会带来很多额外的障碍。

However, you may not need to do this anyway. 但是,您可能仍然不需要这样做。 If your goal is to protect/encrypt the data in transport to/from the server, use SSL/TLS. 如果您的目标是保护/加密与服务器之间的数据传输,请使用SSL / TLS。 If you're not doing client-side authentication, your server needs an SSL certificate but your client does not; 如果您不进行客户端身份验证,则服务器需要SSL证书,但客户端不需要。 the protocol takes care of generating the encryption keys for you in a safe manner. 该协议负责以安全的方式为您生成加密密钥。 If you do want the server to authenticate the client (make it so your server only talks to your clients), you'd need to install a client-side SSL certificate with your app ... this is the private key that you're probably thinking about. 如果您确实希望服务器对客户端进行身份验证(使其进行身份验证,以便服务器仅与客户端通信),则需要在应用中安装客户端SSL证书...这是您要使用的私钥大概在想。

I'll also point you to Application Security for the Android Platform . 我还将为您指出Android平台的应用程序安全性 This book (disclaimer: I wrote the book) has an entire chapter talking about how to design secure Android app-to-server communications, with code examples to illustrate how to implement the appropriate protections. 本书(免责声明:我写过这本书)整整一章都在讨论如何设计安全的Android应用程序到服务器通信,并提供代码示例来说明如何实施适当的保护。 You may want to give it a read. 您可能需要阅读一下。

First of all, in order to implement secure communication between your client application and a server, conceptually speaking, you need only the public key of the server. 首先,为了实现客户端应用程序和服务器之间的安全通信,从概念上讲,您仅需要服务器的公钥。 That allows you to establish a one-way trust relation ship with the server and to establish a secure session, in which the identity of the server is guaranteed. 这样一来,您就可以与服务器建立单向信任关系,并建立安全的会话,从而保证服务器的身份。

While certainly the above method does not provide two-way trust (the client cannot be identified to the server), when establishing the communication channel in most applications, this level of trust is not really required. 尽管上述方法当然不能提供双向信任(无法向服务器标识客户端),但是在大多数应用程序中建立通信通道时,实际上并不需要这种信任级别。

If your requirements are to provide client authentication to the server using public/private keys then things get more complicated because if you put the key in the apk, no matter how much you obfuscate it (including embedding it in a native library) it will only slow down a dedicated nefarious user. 如果您的要求是使用公钥/私钥向服务器提供客户端身份验证,则事情会变得更加复杂,因为如果您将密钥放在apk中,则无论您对其进行多大程度的混淆(包括将其嵌入本机库中),它都只会放慢了专门的邪恶用户的速度。

The only way to store the private key with the client is to encrypt it. 与客户端一起存储私钥的唯一方法是对其进行加密。 But then you have a similar issue of where to store the decrypt key. 但是随后,您在存储解密密钥的位置也遇到了类似的问题。 The easiest solution is to generate a public/private key pair for the user of the client application and ask the user to provide a symmetric encryption/decryption key (which the user will always have to type in) to decrypt the private key each time the user is using the application. 最简单的解决方案是为客户端应用程序的用户生成一个公钥/私钥对,并要求用户提供一个对称的加密/解密密钥(用户将始终必须键入该密钥)以在每次加密时解密私钥。用户正在使用该应用程序。

The alternative would be to use some kind of dedicated cryptographic hardware device similar to a smart card that would store the private key securely but you still have the problem of authorizing your application to read the key from the device (not to mention the complication of interfacing with said device). 另一种选择是使用类似于智能卡的某种专用加密硬件设备,该设备可以安全地存储私钥,但是您仍然存在授权应用程序从设备读取密钥的问题(更不用说接口的复杂性了)与所述设备)。

Now, the question you have to ask yourself is this: "Who are you trying to prevent from reading the private key?" 现在,您必须问自己的问题是: “您试图阻止谁读取私钥?” (of course after answering the other question: "Do you really need a public/private key pair for the client" ). (当然,在回答了另一个问题之后: “您是否真的需要为客户端提供公钥/私钥对” )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM