Php 使用时间戳生成令牌的安全性如何?

Php 使用时间戳生成令牌的安全性如何?,php,android,web-services,security,Php,Android,Web Services,Security,我们有一个Android应用程序,它向web服务发送一些数据,然后web服务将数据保存在MySQL数据库中。如果web服务不是来自应用程序本身,我们希望避免人们使用它。我的意思是,我们希望确保没有人可以对我们的应用程序执行MITM攻击,然后从其他地方向我们的web服务发送请求 我们想出了下一个主意: 我们在Android应用程序和web服务上都包含了一个密码短语,然后在每次请求web服务时,都会以这种方式生成一个使用该密码短语和当前时间戳的令牌: // Pseudo String token =

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

我们想出了下一个主意:

我们在Android应用程序和web服务上都包含了一个密码短语,然后在每次请求web服务时,都会以这种方式生成一个使用该密码短语和当前时间戳的令牌:

// Pseudo
String token = md5(private_passphrase + (timestamp / 60));
然后将生成的令牌发送到web服务,web服务以相同的方式生成另一个令牌并对它们进行比较。如果两者相同,则允许请求

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


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

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

如果攻击者发现了这一点,这实际上并不像您希望的那么难,这很容易成为一个谎言

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


有许多一次性pad算法和库,它们处理这个问题而不涉及时间戳,只需使用google搜索“一次性pad”即可。

我想问你的问题是,你试图防范哪些特定的攻击向量:

  • 基于网络的攻击

    这将无法防止攻击者发出虚假请求。他们只需要拦截一个请求,然后他们就有60秒(平均30秒)的时间使用相同的令牌发出请求

  • 基于网络的长期开发

    这将在某种程度上防止攻击者长期提出虚假请求。由于生成的令牌会很快失效,因此攻击者需要为其要发送的请求的每个时间段获取令牌

  • 一般保护

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

  • 更好的方法 既然您明确地说“MITM”,我建议您在所有通信中使用TLS(HTTPS)。事实上,您可以在应用程序中使用,以确保正确连接到服务器

    您永远无法完全确定请求是否来自您的应用程序。因此,您只需要能够标记滥用的用户。这是一个很好的方法


    但是,请确保对所有流量使用HTTPS作为基线,否则您试图在其上分层的任何“保护”都将无法工作。

    如果两台设备上的时钟不同步,或者存在任何网络延迟,会发生什么情况?@MarkBaker server在给定的时间偏移内检查多个可能的令牌(现在是5分钟)。如果由于任何原因仍然失败,服务器会发回它的当前时间戳,以便客户端可以使用服务器的时间戳再次构建请求。我知道,大约毫秒,这只是示例。在服务器上,我生成多个具有5分钟偏移量的令牌,并比较所有令牌。始终为同一时区获取时间戳,如果匹配失败,服务器将发回它的时间戳,因此客户端可以使用服务器的时间戳再次构建请求。我感兴趣的是这将是一个怎样的寓言。现在代币正在得到验证。我只是想知道我是否可以依赖这个。这基本上是一个邀请欺骗与配方如何做它已经包括在内。所以我第一次就把垃圾发送到你的服务器,得到正确的响应,然后砰的一声,我就在第二次尝试中了。哎呀,你还不在,因为你不知道私人密码,我错了吗?服务器只会在第一次尝试时返回一个时间戳。对,但现在md5并不难破解。它很容易发生碰撞,所以我可以用蛮力穿过它。你应该考虑OTP方法。您的用例是创建它的原因之一:)第二个选项可以使用https。使用它将把所有的麻烦推到传输层。网络服务器。应用程序几乎不会有额外的麻烦。第二种选择是使用https将其移动到传输层。这个应用不需要太多的改动。在服务器端……您可以将其配置为仅在连接正确加密时才接受连接。然后你有你的密码…或者更好,你应该使用一个特定于用户的密码…由于https,它是铠装的,不可重放。MITM也很难。不可能……当涉及到安全性时,这个术语总是有点过于绝对:)