简体   繁体   English

Android facebook-sdk签名安全

[英]Android facebook-sdk signature security

We've been implementing the Facebook Android SDK in our android app which requires to store the app signature on the facebook server so calls from the app to facebook can be validated. 我们一直在我们的Android应用程序中实现Facebook Android SDK,这需要在Facebook服务器上存储应用程序签名,以便可以验证从应用程序到Facebook的调用。 We'd like to use this system for our own backend to make sure it's only being used by our app and regarding to this I have the following questions: 我们希望将此系统用于我们自己的后端,以确保它仅被我们的应用程序使用,并且对此我有以下问题:

(Refer to https://github.com/facebook/facebook-android-sdk/tree/master/facebook/src/com/facebook/android to find the related classes) (请参阅https://github.com/facebook/facebook-android-sdk/tree/master/facebook/src/com/facebook/android查找相关课程)

  1. Obviously, to validate the call by matching signatures, the app's signature needs to be sent to the server. 显然,要通过匹配签名来验证呼叫,需要将应用程序的签名发送到服务器。 Within the sdk, I cannot seem to find where this is done? 在sdk中,我似乎无法找到这样做的地方?
  2. It seems no https is used, is that correct? 似乎没有使用https,这是正确的吗? (Util.java) (Util.java)
  3. Couldn't the signature be sniffed rendering this whole system pointless? 难道签名被嗅到,整个系统无意义吗?
  4. Facebook.java holds the facebook app's signature at the bottom of the file. Facebook.java将facebook应用程序的签名保存在文件的底部。 It might seem trivial to change this. 改变这一点似乎微不足道。 However as far as I understand the signature of an app that sends an Intent can be resolved via that Intent. 但是据我所知,发送Intent的应用程序的签名可以通过Intent解析。 The Android system manages this and therefore a signature cannot be faked. Android系统管理这个,因此签名不能伪造。 However when calling an url can the Android system add the signature to the protocol in such a way it is immutable? 但是,当调用url时,Android系统可以以这种方式将签名添加到协议中吗? I guess not, which makes me wonder about above questions. 我猜不是,这让我对以上问题感到疑惑。

[Edit in reply to nitzan & zapl] [编辑回复nitzan&zapl]

What I'm trying to achieve is the same as why the facebook sdk requires you to store the signature on their server; 我想要实现的是与facebook sdk要求你在他们的服务器上存储签名的原因相同; making sure calls to our backend are sent from our app and nothing else. 确保从我们的应用程序发送对后端的调用,而不是其他任何内容。 We don't want to allow bots or other apps to access our server api. 我们不希望允许机器人或其他应用访问我们的服务器API。 The facebook sdk has methods to check if Intents originate from the Facebook app, which is safe because of the closed management of signatures and Intents by the Android system. facebook sdk有方法来检查Intent是否来自Facebook应用程序,这是安全的,因为Android系统对签名和Intent进行了封闭管理。 The only way to compromise this would be by running a modified Android version which allows for overriding app signatures but the odds of people building and running that are neglectible. 妥协这一点的唯一方法是运行修改后的Android版本,该版本允许覆盖应用程序签名,但人们构建和运行的可能性是可以忽略的。 However running an app, sniffing the signature that is sent over a non https protocol and building an app that uses this signature with api calls isn't. 然而,运行应用程序,嗅探通过非https协议发送的签名并构建使用此签名与api调用的应用程序不是。 It seems the only way to make such a system work is using https, which it seems the facebook sdk doesn't. 似乎使这样一个系统工作的唯一方法是使用https,似乎facebook sdk没有。

Note that the Intent validation methods I'm describing above is different from the url calls to the facebook server. 请注意,我上面描述的Intent验证方法与对facebook服务器的url调用不同。 The Intents are used to have the Facebook app on a device communicate with an app which implements the SDK. Intents用于让设备上的Facebook应用程序与实现SDK的应用程序通信。 The Android system ensures the signature of the Facebook app that is sent with the incoming Intent cannot be faked so the Facebook app->app communication system is safe. Android系统确保与传入的Intent一起发送的Facebook应用程序的签名不能伪造,因此Facebook app-> app通信系统是安全的。 As opposed to this internal system my question is about the external system of outgoing url calls to a server which would be safe if the signature could be sent immutable along the call, basically implementing the same system as the Intent system. 与这个内部系统相反,我的问题是关于外部url调用服务器的外部系统,如果签名可以在调用中发送不可变,那么这将是安全的,基本上实现与Intent系统相同的系统。

[edit 2] [编辑2]

As opposed to what we were assuming, it turns out an app signature is easily fetched. 与我们假设的相反,事实证明,应用程序签名很容易获取。 While apps need to be signed using a private developer key this doesn't compromise security concerning apps on Android, however it obviously cannot be used to validate api calls serverside. 虽然应用程序需要使用私有开发人员密钥进行签名,但这并不会影响Android上应用程序的安全性,但显然无法用于验证服务器端的api调用。

This leads to more questions: 这导致了更多问题:

  1. Why is Facebook implementing this system while it's easily compromised? 为什么Facebook在实施这个系统的同时容易受到损害?
  2. Are there any other known implementations to restrict server api access to a specific app only? 是否有任何其他已知的实现仅限制服务器api访问特定应用程序? (other than obfuscation) (混淆除外)
  1. I don't know. 我不知道。
  2. Yes, it seems to be replacing an fbconnect:// Uri with http:// meaning there is no encryption for connections using this code. 是的,似乎用http://替换fbconnect:// Uri意味着使用此代码的连接没有加密。
  3. I guess yes, try it to verify that. 我想是的,试试验证一下。
  4. It is no problem to change that, you can decompile apks change some code and compile them back if you want. 更改它没有问题,您可以反编译apks更改一些代码并根据需要将其编译回来。 The only thing that you can't do then is to sign the apk again (you lack the secret key required for that). 你不能做的唯一事情是再次签署apk(你没有所需的密钥)。 Or you can use the signature in your own code. 或者您可以在自己的代码中使用签名。
    The signature check for your app happens at installation time and during that permissions you request in your manifest are removed if your signature does not match the requirements. 您的应用程序的签名检查在安装时进行,如果您的签名与要求不符,则您在清单中请求的权限将被删除。 If you update your apk the signature of the new apk is checked against the old existing apk and the upgrade will fail if signatures don't match. 如果您更新了apk,则会根据旧的现有apk检查新apk的签名,如果签名不匹配,升级将失败。 But you can deinstall the old one and install your fake one. 但你可以卸载旧的并安装假的。
    If you send and Intent from your app the system probably includes the package of the sender and you have no access to change that. 如果您从应用程序发送和意图,系统可能包含发件人的包,您无权更改它。

And the whole point of verification to the server is not ultimately a security thing since there is no bulletproof way to authenticate an app. 对服务器进行验证的全部要点最终都不是安全问题,因为没有防弹方式来验证应用程序。 It is used to make it harder for others to abuse the API and it is used to track who is using the api. 它用于使其他人更难滥用API,并用于跟踪谁正在使用api。

An authentication mechanism requires that there is some sort of secret key inside your apk. 身份验证机制要求您的apk中存在某种秘密密钥。 But since you ship that apk to potentially evil customers you have no more control over it and it is possible to extract the key and abuse it. 但是,由于您将该apk发送给潜在的恶意客户,您无法再对其进行控制,因此可以提取密钥并将其滥用。 All you can do is to obfuscate the key so it is harder to get it. 你所能做的就是弄乱密钥,这样就很难搞定。 But it is ultimately not possible. 但这最终是不可能的。


So let's assume you have an app out there that communicates with your backend server and I download your app to my device. 因此,假设您有一个与您的后端服务器通信的应用程序,我将您的应用程序下载到我的设备。 I can then get the .apk off my device, decompile it and find how the communication with your server works - the plaintext before https is ever created. 然后,我可以从我的设备上获取.apk ,对其进行反编译,并查找与服务器的通信是如何工作的 - 在创建https之前的纯文本。 I can also see what the signature of your app is, that is stored in an xml file on the device and in the apk as well. 我还可以看到你的应用程序的签名是什么,它存储在设备和apk中的xml文件中。 Then I go an either modify your app or create a new one that uses the information to behave exactly as yours would do with the exception that it is not your app. 然后,我要么修改你的应用程序,要么创建一个新的应用程序,使用这些信息的行为与你的行为完全相同,除非它不是你的应用程序。 It's no problem to use https and I can also send you your expected signature. 使用https没问题,我也可以发给你预期的签名。

You can't prevent that from happening. 你不能阻止这种情况发生。 You can only make it hard to do that. 你只能这样做很难。

To validate an app running on an untrusted device, a server would have to do something such as require that the communication from the app be digitally signed with a key that only the app holds. 要验证在不受信任的设备上运行的应用程序,服务器必须执行某些操作,例如要求应用程序的通信使用仅包含应用程序的密钥进行数字签名。

The app author would have to conceal the key within the app in such a way that it is relatively difficult to extract for use in an imposter. 应用程序作者必须在应用程序中隐藏密钥,以便提取用于冒名顶替者相对困难。 But it cannot be made impossible to extract. 但是提取它是不可能的。

An imposter armed with the app's extracted key should not based on that alone be able to pretend to be an arbitrary user, but it could allow a real user with a real password to log in (knowingly or unwittingly) from a pretend version of the app. 使用应用程序提取的密钥的冒名顶替者不应该仅凭这一点就可以伪装成任意用户,但它可以允许真正的用户使用真实密码从应用程序的伪装版本登录(有意或无意) 。 Note that actually being able to log into the server may not be a requirement for a fake app designed to simply steal passwords from unwitting users. 请注意,实际上能够登录服务器可能不是一个虚拟应用程序的要求,该应用程序旨在简单地从不知情的用户窃取密码。

SSL is of little value for protecting the app itself, since the app could be installed on a platform with broken SSL or patched to break an internal SSL implementation in order to accomplish interception. SSL对于保护应用程序本身没有什么价值,因为应用程序可以安装在SSL损坏的平台上,也可以修补以打破内部SSL实现以完成拦截。 However, effective SSL could help protect users of the app on un-compromised devices. 但是,有效的SSL可以帮助保护应用程序的用户免受未受损害的设备。

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

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