验证消息来自特定的应用程序/端点
Posted
技术标签:
【中文标题】验证消息来自特定的应用程序/端点【英文标题】:Verifying that message came from a specific app/end point 【发布时间】:2012-12-06 01:35:45 【问题描述】:我正在尝试构建一个安全系统,用于将数据从客户端 android 应用程序传输到运行 php 的 Web 服务器。
我想要做的是确保系统在密码学上是安全的,这样来自应用程序的消息可以被验证为实际上来自应用程序本身,而不是来自可能编写了自定义程序的狡猾用户脚本或使用 cURL 来玩弄系统。
这种验证有很多用例,例如:-
如果应用包含您从中收集指标的广告,您需要验证点击数据是从应用发送的,而不是从发现您的 API 并发送虚拟数据的恶意用户发送的.
该应用可能有一个多项选择调查,并且您需要再次确保从该应用收集调查结果。
应用正在收集 GPS 轨迹,您希望确保数据是从应用本身发送的。
在每种情况下,您都希望确保消息的来源是应用本身,而不仅仅是运行简单脚本来伪造数据的用户。
我考虑过的一些想法:-
SSL - 非常适合保护通道和防止篡改(满足某些要求),但仍不能确保数据源的完整性。
公钥加密 - 客户端应用程序可以使用私钥加密数据,然后将其传输到可以解码的服务器。问题是私钥需要在应用程序中进行硬编码——可以对应用程序进行反编译并提取私钥,然后用于发送虚假数据。
自制算法 - 一个与此非常相似的问题被问到here,其中解决方案仅在“有人找出您的算法”之前有效 - 即不是一个很好的解决方案!
Hash chain - 这似乎是一种非常有趣的方式,它使用一次性密钥来验证从客户端到服务器的每个数据负载,但它再次依赖于应用程序本身,而不是正在反编译,因为密码仍然需要应用程序存储。
我对密码学的有限知识使我认为实际上在理论上不可能以这种方式构建一个完全可验证的系统,因为如果我们不能信任最终客户端或通道,那么没有什么可以建立信任的基础......但也许有一些我忽略了!
【问题讨论】:
使用服务器生成的nonce 来识别交易怎么样?使用 GCM 或其他工具确保只有设备可以接收 nonce。 让 GCM 参与并不是一个坏主意,但我们假设除了通过 Android 应用程序之外没有其他方法可以接收 GCM 消息……也许有(我不知道)。不管怎样,如果我们能想出一个不依赖于特定平台技术的解决方案(如果存在的话),那就太好了。 也许你想试试 security.stackexchange.com。我不是加密专家,但那里有很多。 相关:***.com/questions/8950732/security-from-evil-user 您可能对this感兴趣。 【参考方案1】:这并不难,您只需要对应用进行身份验证即可。您可以使用简单的用户名和密码(通过 SSL)或使用客户端身份验证来执行此操作。在这两种情况下,凭据都需要在应用程序中,攻击者可以提取它们并模拟应用程序。您必须离开它,并且可能实施一些方法来减轻它。
您还可以通过使用非对称密钥(RSA 等)或对称密钥(HMAC 等)对消息进行签名来验证消息。随机数有助于防止重放,其中有人捕获有效签名的消息并将其一遍又一遍地发送到您的服务器。根据您的协议,使用一个的开销可能太多。
为了保护凭证,您可以让客户端生成它们并将它们保存在系统 KeyStore
中,尽管公共 API 不太支持它,请参阅 here 了解一些详细信息。当然,这需要一个额外的步骤,您需要将生成的凭据(例如,公钥)安全地发送到您的服务器,这可能很难正确实施。
无论您做什么,都不要试图发明自己的加密算法或协议,而是使用已建立的加密算法或协议。
【讨论】:
我认为 OP 希望阻止确实拥有合法凭据的用户将其与第三方客户端应用程序一起使用,这并不完全相同。 对我来说不是这样读的,但无论如何。为什么人们总是关闭完全有效的问题?因为他们可能很难回答?真的吗? 1. OP 提到在应用程序中对密钥进行硬编码,因此即使他们实施了您的建议,他们仍然必须添加 DRM 以使密钥更难提取。 2. 不确定这个问题是否针对我(我没有投票结束作为离题。但重复投票可能是合理的。) 最后的问题并不是专门针对你的。我最近看到了很多完全有效的问题。 '来自应用程序的消息可以被验证为实际上来自应用程序本身'在我的书中意味着他想要验证应用程序。 DRM 通常是指将内容绑定到单个(或少量设备)。如果您广泛阅读,这里的“内容”可能是一个关键,但这不会改变他想要验证 app 的事实(“确保消息的来源是应用程序本身” )。我并不是说我给出了完美的答案,只是一些想法。以上是关于验证消息来自特定的应用程序/端点的主要内容,如果未能解决你的问题,请参考以下文章