NSDate:获取与设备时钟无关的精确时间?

可能重复:
如何在应用程序运行之间在本地检测iPhone用户的时钟提升?
有没有办法确定在iOS的实际时间和date(而不是设备的时间)
iOS中是否有可供用户更改的时钟?

简要

我正在使用一个自动更新的订阅应用程序。 当应用程序收到来自Apple的最新收据时,它将expires_date_ms项存储在NSUserDefaults 。 在此date之后的30天,该应用程序与苹果检查,看看订阅是否仍然活跃。 该应用程序可以被视为一个离线应用程序,但它必须连接到互联网每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]使用设备目前的时间(请纠正我,如果我错了)。

是否有任何方法检索设备无关的时间以毫秒为单位? 一个可以准确和可靠地测量而不考虑器件时钟?

虽然凯文和H2CO3是完全正确的,还有其他解决scheme的目的是检查订阅(我希望不需要毫秒的准确度….)

首先观看UIApplicationSignificantTimeChangeNotification以便您得到突然变化时间的通知。 如果你被中止,这甚至会被交付给你(尽pipe如果你被终止,我不相信你会收到)。 当有载波时间更新时会被调用,而且我相信当有手动时间更新(检查)时会调用它。 它也被称为当地午夜,并在夏时制的变化。 重点是,当时间突然改变时,它会经常被调用。

跟踪你进入背景的时间。 跟踪你什么时候回到前台。 如果时间大幅倒退(一两天以上),请提出您希望访问networking来检查事情。 每当你用你的服务器登记时,它应该告诉你它认为是什么时间。 您可以使用它来同步系统。

您可以同样跟踪您的实际运行时间。 如果它与表面运行时间大幅失去同步,那么请求访问networking来同步事物。

我敢肯定,攻击者可以偷偷35天,或者从这个系统中偷走30天,但任何愿意努力工作的人都会破解你的软件,并完全退出。 这里的重点是没有提及的攻击者正在搞乱他们的时钟。 而且你可以抓得很好。

你应该仔细testing这个,并且很踌躇地指责用户的任何事情。 只要连接到您的服务器应该总是足以让一个合法的用户再次工作。

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

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

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

  2. mach_absolute_time()计算自上次重新启动以来的CPU滴答数。 它可以通过CACurrentMediaTime轻松CACurrentMediaTime 。 请注意,只需重新启动设备即可重新设置,所以如果改变时间非常重要,我不确定是否要这样做。

  3. networking时间协议(NTP)是用于同步计算机系统时钟的networking协议。 实际上,所有NTP都在查询时间服务器。 NTP的iOS库可以在这里find。

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

没有这样的东西作为一个不可改变的设备时钟,在重新启动时仍然存在。 获得值得信赖的时间的唯一方法是联系您信任的远程服务器,询问现在是什么时间。