【问题标题】:How secure is generating tokens using a timestamp? [duplicate]使用时间戳生成令牌的安全性如何? [复制]
【发布时间】:2015-06-19 19:25:27
【问题描述】:

我们有一个 Android 应用程序将一些数据发送到网络服务,然后网络服务将其保存在 MySQL 数据库中。如果不是来自应用程序本身,我们希望避免人们使用 Web 服务。我的意思是,我们要确保没有人可以对我们的应用执行 MITM 攻击,然后从其他地方向我们的 Web 服务发送请求。

我们想出了下一个想法:

我们在 Android 应用和网络服务上都包含一个密码,然后对于网络服务的每个请求,都会以这种方式生成一个使用此类密码和当前时间戳的令牌:

// Pseudo
String token = md5(private_passphrase + (timestamp / 60));

然后将生成的令牌发送到 Web 服务,该服务以相同的方式生成另一个令牌并进行比较。如果两者相同,则允许请求。

这个想法是,即使有人嗅探了从我们的应用程序发送的数据包,他们以后也无法使用来自其他来源的相同请求。

这个解决方案有多好和安全?我们更关心的是不让其他人从应用程序外部使用我们的服务,而不是保护我们发送的数据。

【问题讨论】:

  • 如果两个设备上的时钟不同步,或者有任何网络延迟会怎样?
  • @MarkBaker 服务器在给定的时间偏移中检查多个可能的令牌(现在是 5 分钟)。如果由于任何原因仍然失败,服务器会发回它的当前时间戳,以便客户端可以使用服务器的时间戳再次构建请求。

标签: php android web-services security


【解决方案1】:

我要问您的问题是您要防范哪些特定的攻击媒介:

  1. 基于网络的漏洞利用

    这不能防止攻击者发出虚假请求。他们只需要拦截 1 个请求,然后他们将有 60 秒(好吧,平均 30 秒)使用相同的令牌发出请求。

  2. 基于网络的长期漏洞利用

    从长远来看,这将在某种程度上防止攻击者发出虚假请求。由于生成的token很快就失效了,所以攻击者需要为每个想要发送的请求时间段获取一个token。

  3. 通用保护

    这不能防止一般攻击。如果您将私有密码存储在应用程序的 APK 中,那么攻击者可以对 APK 进行逆向工程以获取密码,从而生成他们想要的任何有效令牌。游戏结束。

更好的方法

由于您明确地说“MITM”,我建议您使用 TLS (HTTPS) 进行所有通信。事实上,您可以在应用程序中使用certificate pinning 来确保您正确连接到服务器。

您永远无法完全确定请求来自您的应用。因此,您只需要能够标记滥用用户。 This answer 提出了一个很好的方法。

但是,请务必对所有流量使用 HTTPS 作为基准,否则您尝试叠加的任何“保护”都根本不起作用。

【讨论】:

    【解决方案2】:

    嗯,根据您生成时间戳的方式,除以 60 不一定会得到您想要的结果。我猜你想得到某种“分钟窗口”。时间戳通常以毫秒为单位,这意味着您需要除以 60000。

    如果攻击者发现了这一点,这实际上并不像您希望的那么难,那么这很容易被欺骗。

    此外,如果双方的时钟都关闭超过一分钟,您的系统会将其视为无效的访问尝试,并拒绝访问。这也适用于时区更改,当您的一个客户突然切换时区时,无论出于何种原因,可能是出差。

    市面上有很多one-time pad算法和库,可以在不涉及时间戳的情况下解决这个问题,只需使用google搜索“one-time pad”即可。

    【讨论】:

    • 我知道,大约毫秒,这只是示例。在服务器上,我生成多个偏移 5 分钟的令牌并比较所有令牌。时间戳总是针对同一时区获取,如果匹配失败,服务器会发回它的时间戳,因此客户端可以使用服务器的时间戳再次构建请求。我对这将如何被欺骗感兴趣。现在令牌正在得到验证。我只是想知道我是否可以依靠这个。
    • 这基本上是一个诱骗食谱的邀请,如何做到这一点已经包括在内。所以我只是第一次向你的服务器发送垃圾,得到正确的响应,然后我在第二次尝试。哎呀。
    • 你还没进去,因为你不知道私人密码,我错了吗?服务器只会在第一次尝试时返回一个时间戳。
    • 是的,但是 md5 现在并不难破解。它很容易发生碰撞,所以我可以蛮力通过它。您应该考虑 otp 方法。您的用例是创建它的原因之一 :) 第二个选项可能是使用 https。使用它会将所有麻烦推到​​传输层。网络服务器。该应用程序几乎不会有额外的麻烦。
    • 第二个选项是使用 https 将其移动到传输层。该应用程序不需要太多更改。在服务器端......您可以将其配置为仅在正确加密时接受连接。然后你有你的密码......或者更好的是你应该使用特定于用户的密码......并且由于https它是装甲的并且不可重播。 MITM 也很困难。不可能......好吧,这个词在安全方面总是有点太绝对了:)
    猜你喜欢
    • 1970-01-01
    • 2015-10-07
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 1970-01-01
    • 2019-10-22
    • 2018-07-16
    相关资源
    最近更新 更多