Most app developers will integrate some third party libraries into their apps. If it's to access a service, such as Dropbox or YouTube, or for logging crashes. The number of third party libraries and services is staggering. Most of those libraries and services are integrated by somehow authenticating with the service, most of the time, this happens through an API key. For security purposes, services usually generate a public and private, often also referred to as secret, key. Unfortunately, in order to connect to the services, this private key must be used to authenticate and hence, probably be part of the application. Needless to say, that this faces in immense security problem. Public and private API keys can be extracted from APKs in a matter of minutes and can easily be automated.

假设我有类似的东西,我如何保护密钥:

public class DropboxService  {

    private final static String APP_KEY = "jk433g34hg3";
    private final static String APP_SECRET = "987dwdqwdqw90";
    private final static AccessType ACCESS_TYPE = AccessType.DROPBOX;

    // SOME MORE CODE HERE

}

你认为储存私钥的最佳及最安全的方法是什么?混淆,加密,你怎么看?


当前回答

Whatever you do to secure your secret keys is not going to be a real solution. If developer can decompile the application there is no way to secure the key, hiding the key is just security by obscurity and so is code obfuscation. Problem with securing a secret key is that in order to secure it you have to use another key and that key needs to also be secured. Think of a key hidden in a box that is locked with a key. You place a box inside a room and lock the room. You are left with another key to secure. And that key is still going to be hardcoded inside your application.

因此,除非用户输入PIN或短语,否则无法隐藏密钥。但要做到这一点,你必须有一个方案来管理发生在带外的pin码,这意味着通过不同的渠道。当然,对于谷歌api这样的服务来说,保护密钥是不实际的。

其他回答

老帖子,但仍然足够好。我认为把它藏在一个。so库中会很棒,当然使用NDK和c++。.so文件可以在十六进制编辑器中查看,但祝你能反编译它:P

Whatever you do to secure your secret keys is not going to be a real solution. If developer can decompile the application there is no way to secure the key, hiding the key is just security by obscurity and so is code obfuscation. Problem with securing a secret key is that in order to secure it you have to use another key and that key needs to also be secured. Think of a key hidden in a box that is locked with a key. You place a box inside a room and lock the room. You are left with another key to secure. And that key is still going to be hardcoded inside your application.

因此,除非用户输入PIN或短语,否则无法隐藏密钥。但要做到这一点,你必须有一个方案来管理发生在带外的pin码,这意味着通过不同的渠道。当然,对于谷歌api这样的服务来说,保护密钥是不实际的。

很少有想法,在我看来,只有第一个想法给了一些保证:

Keep your secrets on some server on internet, and when needed just grab them and use. If user is about to use dropbox then nothing stops you from making request to your site and get your secret key. Put your secrets in jni code, add some variable code to make your libraries bigger and more difficult to decompile. You might also split key string in few parts and keep them in various places. use obfuscator, also put in code hashed secret and later on unhash it when needed to use. Put your secret key as last pixels of one of your image in assets. Then when needed read it in your code. Obfuscating your code should help hide code that will read it.

如果你想快速看看阅读你的apk代码是多么容易,然后获取APKAnalyser:

http://developer.sonymobile.com/knowledge-base/tool-guides/analyse-your-apks-with-apkanalyser/

将秘密保存在firebase数据库中,并在应用程序启动时从中获取, 它比调用web服务好得多。

最安全的解决方案是将密钥保存在服务器上,并通过服务器路由所有需要该密钥的请求。这样,密钥就不会离开服务器,所以只要服务器是安全的,那么密钥也是安全的。当然,这种解决方案有性能成本。