在应用程序中存储和保护私有API密钥的最佳实践

本文翻译自:Best practice for storing and protecting private API keys in applications [closed]

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. 如果要访问服务(例如Dropbox或YouTube)或记录崩溃。 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. 大多数这些库和服务通过某种方式与服务进行身份验证集成在一起,大多数情况下,这是通过API密钥进行的。 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. 可以在几分钟内从APK中提取公共和私有API密钥,并且可以轻松实现自动化。

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? 混淆,加密,您怎么看?


#1楼

参考:https://stackoom.com/question/z8Zx/在应用程序中存储和保护私有API密钥的最佳实践


#2楼

The App-Secret key should be kept private - but when releasing the app they can be reversed by some guys. App-Secret密钥应保持私密性-但是在发布应用程序时,某些人可能会将其撤消。

for those guys it will not hide, lock the either the ProGuard the code. 对于那些不会隐藏的家伙,请锁定ProGuard的代码。 It is a refactor and some payed obfuscators are inserting a few bitwise operators to get back the jk433g34hg3 String. 这是一个重构,一些付费混淆器正在插入一些按位运算符,以获取jk433g34hg3 String。 You can make 5 -15 min longer the hacking if you work 3 days :) 如果您工作3天,则可以使黑客入侵时间延长5 -15分钟:)

Best way is to keep it as it is, imho. 最好的方法是保持原样,恕我直言。

Even if you store at server side( your PC ) the key can be hacked and printed out. 即使存储在服务器端(您的PC上),该密钥也可以被黑客破解并打印出来。 Maybe this takes the longest? 也许这需要最长的时间? Anyhow it is a matter of few minutes or a few hours in best case. 无论如何,最好是几分钟或几个小时。

A normal user will not decompile your code. 普通用户不会反编译您的代码。


#3楼

Few ideas, in my opinion only first one gives some guarantee: 在我看来,只有很少的想法可以保证:

  1. Keep your secrets on some server on internet, and when needed just grab them and use. 将您的秘密保存在Internet上的某个服务器上,并在需要时将其抓取并使用。 If user is about to use dropbox then nothing stops you from making request to your site and get your secret key. 如果用户将要使用保管箱,那么没有什么可以阻止您向您的站点发出请求并获取您的密钥。

  2. Put your secrets in jni code, add some variable code to make your libraries bigger and more difficult to decompile. 将您的秘密放入jni代码中,添加一些可变代码以使您的库更大,更难于反编译。 You might also split key string in few parts and keep them in various places. 您也可以将密钥字符串分成几部分,并放在不同的位置。

  3. use obfuscator, also put in code hashed secret and later on unhash it when needed to use. 使用混淆器,也将代码散列在秘密中,稍后在需要使用时对其进行散列。

  4. 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. 混淆代码应有助于隐藏将读取该代码的代码。

If you want to have a quick look at how easy it is to read you apk code then grab APKAnalyser: 如果您想快速了解一下阅读apk代码的难易程度,请抓住APKAnalyser:

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


#4楼

  1. As it is, your compiled application contains the key strings, but also the constant names APP_KEY and APP_SECRET. 实际上,已编译的应用程序包含键字符串,还包含常量名称APP_KEY和APP_SECRET。 Extracting keys from such self-documenting code is trivial, for instance with the standard Android tool dx. 例如,使用标准的Android工具dx,从这样的自记录代码中提取密钥很简单。

  2. You can apply ProGuard. 您可以应用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. 然后,提取密钥需要花费更多时间,以弄清楚哪个字符串可以达到什么目的。

    Note that setting up ProGuard shouldn't be as difficult as you fear. 请注意,设置ProGuard并不像您担心的那样困难。 To begin with, you only need to enable ProGuard, as documented in project.properties. 首先,仅需要启用ProGuard,如project.properties中所述。 If there are any problems with third-party libraries, you may need to suppress some warnings and/or prevent them from being obfuscated, in proguard-project.txt. 如果第三方库有任何问题,则可能需要在proguard-project.txt中禁止某些警告和/或防止混淆它们。 For instance: 例如:

     -dontwarn com.dropbox.** -keep class com.dropbox.** { *; } 

    This is a brute-force approach; 这是蛮力的方法; you can refine such configuration once the processed application works. 您可以在处理后的应用程序正常运行后改进此类配置。

  3. You can obfuscate the strings manually in your code, for instance with a Base64 encoding or preferably with something more complicated; 您可以在代码中手动混淆字符串,例如使用Base64编码,或者最好使用更复杂的东西。 maybe even native code. 甚至本地代码。 A hacker will then have to statically reverse-engineer your encoding or dynamically intercept the decoding in the proper place. 然后,黑客将不得不对您的编码进行静态反向工程或在适当的位置动态拦截解码。

  4. You can apply a commercial obfuscator, like ProGuard's specialized sibling DexGuard . 您可以应用商业混淆器,例如ProGuard的专业兄弟姐妹DexGuard It can additionally encrypt/obfuscate the strings and classes for you. 它还可以为您加密/混淆字符串和类。 Extracting the keys then takes even more time and expertise. 这样,提取密钥将花费更多的时间和专业知识。

  5. 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. 从本质上讲,客户端上的任何内容都是坚不可摧的,但是您当然可以提高标准。

(I am the developer of ProGuard and DexGuard) (我是ProGuard和DexGuard的开发人员)


#5楼

Ages old post, but still good enough. 年代久远,但仍然足够好。 I think hiding it in an .so library would be great, using NDK and C++ of course. 我认为使用NDK和C ++将其隐藏在.so库中会很好。 .so files can be viewed in a hex editor, but good luck decompiling that :P .so文件可以在十六进制编辑器中查看,但很幸运,反编译:P


#6楼

The only true way to keep these private is to keep them on your server, and have the app send whatever it is to the server, and the server interacts with Dropbox. 保持私有性的唯一真实方法是将它们保留在服务器上,并让应用将所有内容发送到服务器,然后服务器与Dropbox进行交互。 That way you NEVER distribute your private key in any format. 这样,您就永远不会以任何格式分发私钥。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值