问题描述
大多数应用程序开发人员都会将一些第三方库集成到他们的应用程序中.如果要访问服务(例如Dropbox或YouTube)或记录崩溃.第三方库和服务的数量惊人.大多数这些库和服务通过某种方式与服务进行身份验证集成在一起,大多数情况下,这是通过API密钥进行的.为了安全起见,服务通常会生成一个公共密钥和私有密钥,通常也称为秘密密钥.不幸的是,为了连接到服务,必须使用此私钥进行身份验证,因此可能是应用程序的一部分.不用说,这面临着巨大的安全问题.可以在几分钟内从APK中提取公共和私有API密钥,并且可以轻松实现自动化.
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.
假设我有类似的东西,我该如何保护密钥:
Assuming I have something similar to this, how can I protect the secret key:
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
}
您认为存储私钥的最佳和最安全的方法是什么?混淆,加密,您怎么看?
What is in your opinion the best and most secure way to store the private key? Obfuscation, encryption, what do you think?
推荐答案
-
就这样,已编译的应用程序包含密钥字符串,还包含常量名称APP_KEY和APP_SECRET.例如,使用标准的Android工具dx,从这样的自记录代码中提取密钥很简单.
As it is, your compiled application contains the key strings, but also the constant names APP_KEY and APP_SECRET. Extracting keys from such self-documenting code is trivial, for instance with the standard Android tool dx.
您可以应用ProGuard.它将使键字符串保持不变,但是将删除常量名称.只要有可能,它还将使用简短,无意义的名称重命名类和方法.然后,提取密钥需要花费更多时间,才能弄清楚哪个字符串可以达到什么目的.
You can apply ProGuard. It will leave the key strings untouched, but it will remove the constant names. It will also rename classes and methods with short, meaningless names, where ever possible. Extracting the keys then takes some more time, for figuring out which string serves which purpose.
请注意,设置ProGuard并不像您担心的那样困难.首先,仅需要启用ProGuard,如project.properties中所述.如果第三方库有任何问题,则可能需要在proguard-project.txt中禁止某些警告和/或防止混淆它们.例如:
-dontwarn com.dropbox.**
-keep class com.dropbox.** { *; }
这是蛮力的方法;您可以在处理后的应用程序正常运行后改进此类配置.
您可以在代码中手动混淆字符串,例如,使用Base64编码或最好使用更复杂的字符串;甚至本机代码.然后,黑客将不得不对您的编码进行静态反向工程或在适当的位置动态拦截解码.
You can obfuscate the strings manually in your code, for instance with a Base64 encoding or preferably with something more complicated; maybe even native code. A hacker will then have to statically reverse-engineer your encoding or dynamically intercept the decoding in the proper place.
您可以应用商业混淆器,例如ProGuard的专门兄弟 DexGuard .它还可以为您加密/混淆字符串和类.这样,提取密钥将花费更多的时间和专业知识.
You can apply a commercial obfuscator, like ProGuard's specialized sibling DexGuard. It can additionally encrypt/obfuscate the strings and classes for you. Extracting the keys then takes even more time and expertise.
您也许可以在自己的服务器上运行部分应用程序.如果您可以将钥匙放在那里,那么它们是安全的.
You might be able to run parts of your application on your own server. If you can keep the keys there, they are safe.
最后,这是您必须进行的经济折衷:密钥有多重要,您可以负担多少时间或软件,对密钥感兴趣的黑客有多精明,将花费多少时间?他们想花钱,在密钥被黑客入侵之前有多少延迟,成功的黑客将在多大程度上分发密钥,等等.像密钥之类的小信息比整个应用程序更难保护.从本质上讲,客户端上没有任何东西是坚不可摧的,但是您当然可以提高标准.
In the end, it's an economic trade-off that you have to make: how important are the keys, how much time or software can you afford, how sophisticated are the hackers who are interested in the keys, how much time will they want to spend, how much worth is a delay before the keys are hacked, on what scale will any successful hackers distribute the keys, etc. Small pieces of information like keys are more difficult to protect than entire applications. Intrinsically, nothing on the client-side is unbreakable, but you can certainly raise the bar.
(我是ProGuard和DexGuard的开发人员)
(I am the developer of ProGuard and DexGuard)
这篇关于在应用程序中存储和保护私有API密钥的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!