在使用Facebook开发Android应用时,您需要将应用的密钥哈希上传到他们的网站。有了这个,他们声称他们能够验证对他们的服务器的调用是否实际上来自您的应用程序。
我已经阅读了这个问题How does Facebook verifies mobile apps,但它并没有真正提供这个问题的实际实现。我试过查看facebook库的源代码,但无法弄清楚。
哪些数据是从Android应用程序发出的,以及可以在服务器中针对此哈希验证的加密? facebook实施的方法是否安全?
如果是,并且它可以在任何服务器中实现,我可以使用它来验证我的服务器我的应用程序没有用不同的代码重新编译(这往往经常发生:()
我目前正在以这种方式实施这一想法:
Signature[] sigs = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
for (Signature sig : sigs) {
verifyInServer(sig.hashCode());
}
其中verifyInServer是伪代码,用于针对具有签名存储值的服务器进行的检查。它现在已经有效,但我不确定它是否安全,而且我更愿意检查一个密钥哈希(它的公开)而不是这个签名数据(我不是确定它是私有的还是不能被用户欺骗。)
答案 0 :(得分:9)
@ Zbysek的答案可能是正确的,因为Facebook应用程序很可能是实际执行验证的应用程序。如果没有这个应用程序的源代码,很难确定,但我们可以通过检查Facebook API库项目的源代码来推断一些事情,特别是在AuthorizationClient
和{{1}中编码的登录过程类。
首先,客户端验证 Facebook应用程序
本身已正确签名。这是预期的,因为你不会
想要提供您的登录凭据到假应用程序冒充
Facebook的。这是在Session
类中完成的(也是在
对于已弃用的方法,NativeProtocol
类。这是仅提及API 中的签名,因此如果有其他验证,则可以通过Facebook应用程序本身或服务器完成。
Facebook
最终会创建一个Session.open()
来尝试一系列可能的处理程序。其中一个(第一个使用,如果AuthorizationClient
允许它)是Facebook应用程序本身(例如SessionLoginBehavior
,但还有其他)。
这些KatanaLoginDialogAuthHandler
个对象最终使用AuthHandler
来调用tryIntent()
来调用Facebook应用程序。
总而言之,登录过程:
startActivityForResult()
。这是一个关键部分,因为活动始于startActivityForResult()
(但不以startActivityForResult()
开头)可以使用getCallingActivity()
来了解身份(包裹)和来电者的班级名称。
因此,Facebook应用程序可以轻松使用此信息查询startActivity()
,获取您的应用程序的签名,将该数据与应用程序ID一起传递到服务器,并验证它们比赛。由于Facebook应用程序本身已签名,您的应用程序可以信任此结果。
我承认这是所有的猜测,但考虑到我们所知道的,似乎有点可信:)
不幸的是,这也意味着这种机制不太可能被复制用于保证真实性。除非你是Facebook或谷歌(谷歌播放服务有类似的签名验证功能,例如地图)或者可以某种方式确保你的第二个应用程序也可用于每个设备。
答案 1 :(得分:8)
通过SDK调用的原生Facebook应用程序验证应用程序的签名 - API built in in Android OS - 它检查是否匹配哈希。当应用程序由私钥签名时,哈希是一种公钥。
可以使用JS SDK登录用户而不是本机应用程序,然后哈希不会被验证(可以被欺骗)。无论如何,他们认为这是非问题,因为在这种情况下,用户将看到他登录的应用程序并且无论如何都需要允许访问(登录流程通过FB服务器并显示应用程序名称)。你不能在Facebook cookie中欺骗你。
还有一个人可能会弄乱Facebook natve应用程序让它看到非签名的应用程序,因为其他一些签名的应用程序知道另一个的哈希(但如果可能的话,这将是相当艰巨的任务,需要破解它,更改它,它只适用于安装了修改过的原生FB应用程序的系统。