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

}

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


当前回答

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

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/

其他回答

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

另一种方法是一开始就不要在设备上保存秘密!请参阅移动API安全技术(特别是第3部分)。

使用历史悠久的间接传统,分享API端点和应用程序身份验证服务之间的秘密。

当您的客户端想要进行API调用时,它要求应用程序认证服务对其进行身份验证(使用强大的远程认证技术),并接收由秘密签名的时间限制令牌(通常是JWT)。

令牌随每个API调用一起发送,端点可以在对请求执行之前验证其签名。

真正的秘密永远不会出现在设备上;事实上,应用程序从来不知道它是否有效,它只是请求身份验证并传递结果令牌。间接的好处是,如果你想改变秘密,你可以不需要用户更新他们安装的应用程序。

所以如果你想保护你的秘密,从一开始就不要把它放在你的应用程序中是一个很好的方法。

app - secret密钥应该是私有的-但在发布应用程序时 它们可以被某些人逆转。

对于那些家伙,它不会隐藏,锁定或ProGuard的代码。这是一个重构,一些付费的混淆器正在插入一些位操作符以恢复jk433g34hg3 字符串。如果你工作3天,你可以延长5 -15分钟的黑客时间:)

恕我直言,最好的办法就是保持现状。

即使你存储在服务器端(你的PC),密钥也可能被黑客攻击并打印出来。也许这个花的时间最长?无论如何,在最好的情况下,这只是几分钟或几个小时的问题。

普通用户不会反编译你的代码。

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

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

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/