secure_ist_time_guard

A Flutter package designed to provide a highly secure, tamper-resistant, offline-capable Indian Standard Time (IST) source for your apps.

secure_ist_time_guard addresses the common vulnerability where users manipulate device time to bypass time-based restrictions. It anchors network time (flutter_kronos) to device uptime rather than the easily manipulated system clock.

Features

  • Offline Support: Continues to provide secure time even when disconnected from the internet.
  • Tamper Detection: Detects if the device time has been manipulated (e.g., timezone changes or clock shifts) and flags it.
  • Native Uptime Anchoring: Uses SystemClock.elapsedRealtime() (Android) and ProcessInfo.systemUptime (iOS) to track elapsed time, which are unaffected by manual time changes.
  • Auto-Syncing: Maintains synchronization with an NTP server whenever the network is available.

Getting Started

Add secure_ist_time_guard to your pubspec.yaml:

dependencies:
  secure_ist_time_guard: ^0.0.1

Usage

The ISTService is an auto-initializing singleton. You can access the secure time from anywhere in your app.

1. Basic Setup

Simply access the instance to ensure it is initialized:

import 'package:secure_ist_time_guard/secure_ist_time_guard.dart';

// The service auto-initializes upon first access.
final istService = ISTService();

2. Force Syncing

It's highly recommended to sync the time when the user performs a critical action (like logging in) or when the app resumes:

await ISTService().sync();

3. Getting Secure IST Time

DateTime currentSecureTime = ISTService().currentDateTime;
print(currentSecureTime);

4. Handling Tampering

The service automatically flags tampering if the system time diverges significantly from the trusted uptime-anchored time.

if (ISTService().isTampered) {
  // Show a bottom sheet blocking the user until they fix their time
  ISTService().showTimeManipulationBottomSheet(context);
}

Limitations & Requirements

  1. Device Restart: The uptime counter resets on device reboot. The app MUST connect to the internet at least once after a reboot to establish a new trusted baseline. If opened offline after a reboot, it will fall back to the potentially untrusted device time.
  2. Fresh Install / Data Cleared: Trusted time is cached locally. A fresh install or data wipe requires an initial online sync.
  3. Rooted / Jailbroken Devices: While this package protects against standard time manipulation, advanced tools on rooted/jailbroken devices could potentially spoof system uptime APIs.

How it Works

  1. Fetches real UTC time from an NTP server via flutter_kronos.
  2. Simultaneously records the native device uptime.
  3. Caches the network time and the uptime baseline securely via SharedPreferences.
  4. When queried (currentDateTime), it calculates: Cached Network Time + (Current Uptime - Baseline Uptime).
  5. Converts the calculated time directly to IST (UTC+05:30) and returns a standard DateTime object.