8

可能重复:
如何在应用程序运行之间本地检测用户的 iPhone 时钟提前?
有没有办法确定 iOS 中的实际时间和日期(不是设备的时间)
iOS 中有没有可以使用的时钟,用户无法更改

简短的

我正在使用基于自动更新订阅的应用程序。当应用程序收到来自 Apple 的最新收据时,它会将expires_date_ms密钥存储在NSUserDefaults. 在该日期后的 30 天,该应用程序会与 Apple 核对订阅是否仍然有效。该应用程序可以被视为离线应用程序,但它必须每 30 天连接一次互联网以检查订阅状态。这个时间比较将用于告诉用户他/她必须连接。

问题

我正在使用下面的代码将当前时间与expires_date_ms

NSTimeInterval expDateMS = [[productInfo objectForKey:@"expires_date_ms"] doubleValue];
NSTimeInterval currentDateMS = ([[NSDate date] timeIntervalSince1970] * 1000);

if (currentDateMS > expDateMS)
    subExpired = YES;

这很好,效果很好,但据我所知,有一个可以利用的漏洞 - 如果用户将设备的时钟设置回一小时/月/十年,时间比较将变得不可靠,因为[NSDate date]使用设备的当前时间(请如我错了请纠正我)。

问题

有没有办法以毫秒为单位检索与设备无关的时间?一种可以在不考虑设备时钟的情况下准确可靠地测量?

4

4 回答 4

6

您需要从可靠的官方时间服务器连接/检索信息,并在您的应用程序中使用该时间数据。例如,这是一个具有易于使用的 API 的世界时间服务器

于 2012-08-31T19:40:37.230 回答
6

虽然 Kevin 和 H2CO3 是完全正确的,但还有其他用于检查订阅的解决方案(我希望不需要毫秒精度......)

首先观看UIApplicationSignificantTimeChangeNotification,以便您在时间突然变化时收到通知。如果您被停职,这甚至会交付给您(尽管我不相信如果您被终止,您将不会收到)。当有运营商时间更新时会调用它,我相信当有手动时间更新(检查)时会调用它。它还在当地午夜和 DST 更改时调用。关键是当时间突然改变时,它经​​常被调用。

跟踪您进入后台的时间。跟踪您回到前台的时间。如果时间从根本上倒退(超过一两天),请建议您访问网络进行检查。每当您向服务器登记时,它应该会告诉您它认为的时间。您可以使用它来同步系统。

您可以类似地跟踪您的实际运行时间。如果它与明显的运行时间严重不同步,那么再次请求访问网络以同步。

我敢肯定,攻击者可以从这个系统中偷偷溜出 35 天或任何时间,而不是 30 天,但是任何愿意努力工作的人都会破解您的软件并完全退出。这里的重点是那些只是在弄乱他们的时钟的未提交攻击者。而且你可以很好地捕捉到。

您应该仔细测试这一点,并且非常犹豫地指责用户任何事情。只需连接到您的服务器就足以让合法用户再次工作。

于 2012-08-31T19:58:38.543 回答
4

以下是我能想到的三个选项:

  1. clock_gettime(CLOCK_MONOTONIC)获取当前系统正常运行时间。这是相对不可靠的,因为如果用户重新启动,它会被重置。您可以保存最后使用的值并在启动时使用最后保存的值作为偏移量,但这样做的问题是不会计算设备关闭的时间。

  2. mach_absolute_time()计算自上次重新启动以来的 CPU 滴答数。它可以很容易地通过CACurrentMediaTime. 请注意,这可以通过重新启动设备简单地重置,所以如果更改时间非常重要,我不确定你是否会这样做。

  3. 网络时间协议 (NTP) 是一种用于同步计算机系统时钟的网络协议。实际上,所有 NTP 都是在查询时间服务器。可以在此处找到用于 NTP 的 iOS 库。

所以前两种方法不需要连接,而第三种方法需要。但是,第三种方法是唯一万无一失的方法。

于 2012-08-31T19:56:02.250 回答
2

不存在在重新启动后仍然存在的非可变设备时钟。获得可信时间的唯一方法是联系您信任的远程服务器并询问其时间。

于 2012-08-31T19:40:52.000 回答