8

重複の可能性:
アプリの実行間で、ユーザーによる iPhone クロックの進行をローカルで検出するにはどうすればよいですか?
iOS で実際の時刻と日付 (デバイスの時刻ではない) を特定する方法はありますか
? ユーザーが変更できない、使用できる iOS の時計はありますか?

簡単に

自動更新可能なサブスクリプション ベースのアプリを使用しています。アプリは、Apple から最新のレシートを受け取ると、expires_date_msキーをに保存しますNSUserDefaults。その日から 30 日後、アプリは Apple にチェックを入れ、サブスクリプションがまだ有効かどうかを確認します。アプリはオフライン アプリと見なすことができますが、サブスクリプション ステータスを確認するには、30 日ごとに 1 回インターネットに接続する必要があります。この時間比較は、接続する必要があることをユーザーに伝えるために使用されます。

問題

以下のコードを使用して、現在の時刻を と比較していますexpires_date_ms

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

if (currentDateMS > expDateMS)
    subExpired = YES;

これはうまく機能しますが、悪用される可能性のある抜け穴があることがわかります。ユーザーがデバイスの時計を 1 時間/1 か月/10 年戻すと[NSDate date]、デバイスの現在の時刻を使用するため、時間の比較が信頼できなくなります (お願いします)。間違っていたら訂正してください)。

質問

デバイスに依存しない時間をミリ秒単位で取得する方法はありますか? デバイスのクロックに関係なく、正確かつ確実に測定できるものはありますか?

4

4 に答える 4

6

KevinとH2CO3は完全に正しいですが、サブスクリプションをチェックする目的で他のソリューションがあります(ミリ秒の精度が必要ないことを願っています...)

UIApplicationSignificantTimeChangeNotification時間が急に変わったときに通知を受け取るように、最初に見てください。これは、あなたが停止された場合でもあなたに届けられます(あなたが停止された場合、あなたがそれを受け取るとは思わないが)。これは、キャリアタイムの更新があるときに呼び出され、手動の時間更新があるときに呼び出されると思います(チェック)。また、現地の深夜およびDSTの変更時に呼び出されます。ポイントは、時間が急に変わるとかなり頻繁に呼ばれるということです。

バックグラウンドに入ったときの時間を追跡します。フォアグラウンドに戻ったときを追跡します。時間が大幅に遅れる場合(1日か2日以上)、ネットワークにアクセスして確認することをお勧めします。サーバーにチェックインするときはいつでも、サーバーが何時だと思うかを教えてくれるはずです。これを使用して、システムを同期できます。

同様に、実際の実行時間を追跡できます。見かけのランタイムと大幅に同期が取れなくなった場合は、ネットワークへのアクセスを要求して同期を取ります。

攻撃者はこのシステムから30日ではなく35日か何かをこっそり持ち出すことができると確信していますが、そのように一生懸命働くことをいとわない人は、ソフトウェアをクラックして完全にチェックアウトするだけです。ここでの焦点は、時計をいじっているだけのコミットされていない攻撃者です。そして、あなたはかなりうまく捕まえることができます。

これを注意深くテストし、ユーザーを非難することを非常に躊躇する必要があります。サーバーに接続するだけで、正当なユーザーが再び機能するようになります。

于 2012-08-31T19:58:38.543 に答える
6

信頼できる公式のタイム サーバーに接続して情報を取得し、アプリでその時刻データを使用する必要があります。たとえば、使いやすい API を備えたワールド タイム サーバーは次のとおりです。

于 2012-08-31T19:40:37.230 に答える
4

私が考えることができる3つのオプションは次のとおりです。

  1. clock_gettime(CLOCK_MONOTONIC)現在のシステム稼働時間を取得します。これは、ユーザーが再起動するとリセットされるため、比較的信頼性が低くなります。最後に使用した値を保存し、起動時に最後に保存した値をオフセットとして使用できますが、これの問題は、デバイスがオフになった時間が計算されないことです。

  2. mach_absolute_time()最後の再起動以降の CPU ティック数をカウントします。から簡単に取得できますCACurrentMediaTime。これはデバイスを再起動するだけでリセットできることに注意してください。そのため、時間を変更することが非常に重要な場合は、このようにするかどうかはわかりません.

  3. ネットワーク タイム プロトコル (NTP) は、コンピューター システムのクロックを同期するためのネットワーク プロトコルです。実際には、すべての NTP はタイム サーバーにクエリを実行します。NTP 用の iOS ライブラリは、ここにあります。

したがって、最初の 2 つの方法は接続を必要としませんが、3 番目の方法は接続を必要とします。ただし、3 番目の方法が唯一の確実な方法です。

于 2012-08-31T19:56:02.250 に答える
2

再起動後も持続する変更不可能なデバイス クロックなどというものはありません。信頼できる時刻を取得する唯一の方法は、信頼できるリモート サーバーに接続して、その時刻を確認することです。

于 2012-08-31T19:40:52.000 に答える