trusted_time 1.0.3
trusted_time: ^1.0.3 copied to clipboard
Tamper-proof, offline-safe, multi-source trusted time for Flutter. Provides reliable timestamps immune to system clock manipulation.
TrustedTime #
TrustedTime is a high-integrity, production-grade time guardian for Flutter. It provides a tamper-proof UTC clock anchored to hardware monotonic oscillators, ensuring your app's temporal logic remains perfect even if the system clock is manipulated.
Architecture • Contributing • Security • Changelog
Unlike DateTime.now(), which depends on the user-modifiable system clock, TrustedTime synchronizes with trusted network time sources and anchors that time to the device’s hardware monotonic clock — ensuring timestamps remain correct even if users change their device time or go offline.
Why TrustedTime? #
Many apps rely on time for correctness and security:
- Trial expirations
- Subscription billing
- Ticket validity
- Rate limiting
- Audit logging
- Token expiration
Unfortunately, system time is untrusted — users can move it forward or backward at will.
TrustedTime solves this by providing a secure virtual clock that:
✅ Works offline after first sync ✅ Detects clock tampering automatically ✅ Persists across app restarts ✅ Has near-zero runtime overhead ✅ Works across Android, iOS, Web, and Desktop
Platform Support #
| Android | iOS | Web | macOS | Windows | Linux |
|---|---|---|---|---|---|
| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Features #
- Tamper-Proof Time: Anchors network UTC to hardware monotonic uptime.
- Multi-Source Consensus: Quorum-based resolution via NTP and HTTPS.
- Secure Persistence: Encrypted state recovery across app restarts.
- High Performance: Synchronous, zero-latency access with <1μs overhead.
- Offline Ready: Continues providing trusted time without connectivity once anchored.
- Integrity Monitoring: Real-time event streams for clock jumps and reboots.
Installation #
Add TrustedTime to your pubspec.yaml via CLI:
flutter pub add trusted_time
Platform-Specific Setup #
Android
Ensure your AndroidManifest.xml (usually found in android/app/src/main/AndroidManifest.xml) includes the Internet permission:
<uses-permission android:name="android.permission.INTERNET" />
iOS / macOS / Windows / Linux / Web
No additional setup or permissions are required. The library automatically leverages native APIs for monotonic timing and secure storage.
Quick Start #
1️⃣ Initialize once at app startup #
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Await initialization to ensure hardware monotonic anchoring is established.
await TrustedTime.initialize();
runApp(MyApp());
}
2️⃣ Get trusted time anywhere #
final now = TrustedTime.now();
final unixMs = TrustedTime.nowUnixMs();
final iso = TrustedTime.nowIso();
3️⃣ Check trust state #
if (TrustedTime.isTrusted) {
// Time is verified and safe to use
} else {
// Still syncing or integrity lost
}
4️⃣ Listen for tampering #
TrustedTime.onIntegrityLost.listen((_) {
print('System clock changed or device rebooted');
});
5️⃣ Force resync if needed #
await TrustedTime.forceResync();
Common Use Cases #
Ticketing & Access Control #
Prevent users from activating passes early or extending them by changing device time.
Trials & Subscriptions #
Ensure “7-day trials” are exactly 7 days — even if the user adjusts their clock or goes offline.
Anti-Fraud & Compliance #
Use trusted timestamps for audit logs, transaction signing, and security-critical workflows.
Rate Limiting & Cooldowns #
Prevent cooldown bypass attacks caused by local clock manipulation.
How It Works (Simple Explanation) #
TrustedTime establishes a Trust Anchor:
- It queries multiple network time sources (NTP + HTTPS).
- It filters bad or slow sources using a quorum algorithm.
- It stores the verified network time alongside the device’s monotonic uptime.
- From then on, it computes:
trustedNow = (currentUptime - uptimeAtSync) + networkTimeAtSync
Because monotonic uptime cannot be changed by the user, this clock remains accurate even if:
- The system time is modified
- The device goes offline
- The app is restarted
Only a device reboot resets uptime — which TrustedTime detects and automatically resynchronizes.
Advanced Configuration #
await TrustedTime.initialize(
config: TrustedTimeConfig(
refreshInterval: Duration(hours: 12),
ntpServers: ['time.google.com', 'pool.ntp.org'],
httpsSources: ['https://www.google.com', 'https://www.cloudflare.com'],
maxLatency: Duration(seconds: 2),
minimumQuorum: 2,
persistState: true,
),
);
Platform Behavior #
Android #
- Uses
SystemClock.elapsedRealtime()(hardware monotonic clock) - Detects manual time and timezone changes automatically
- No setup required
iOS #
- Uses
ProcessInfo.systemUptime - Detects system clock changes automatically
- No setup required
Web & Desktop #
- Uses HTTPS time sources
- Uses browser/OS monotonic timers
- Works offline after sync
Performance #
| Operation | Cost |
|---|---|
TrustedTime.now() |
< 1μs |
| Initial sync | ~100–500ms |
| Memory overhead | ~50 KB |
| Background CPU | Zero when idle |
TrustedTime performs no background polling and uses zero timers once synced.
Security Model #
TrustedTime protects against:
| Threat | Protected |
|---|---|
| Manual clock change | ✅ |
| Offline replay | ✅ |
| Trial extension | ✅ |
| System time rollback | ✅ |
| App restart abuse | ✅ |
| Network MITM (single server) | ✅ |
Limitations:
- Requires internet on first launch
- Cannot protect against hardware-level clock manipulation
Comparison #
| Capability | DateTime.now() |
flutter_time_guard |
flutter_kronos |
TrustedTime |
|---|---|---|---|---|
| Trusted timestamps | ❌ | ❌ | ⚠️ Basic | ✅ |
| Offline after sync | ❌ | ⚠️ Limited | ✅ | ✅ |
| Detects clock tampering | ❌ | ✅ | ⚠️ Partial | ✅ |
| Multi-source consensus | ❌ | ❌ | ❌ | ✅ |
| HTTPS fallback | ❌ | ❌ | ❌ | ✅ |
| Drift/uncertainty metadata | ❌ | ❌ | ❌ | ✅ |
| Cross-platform | ⚠️ | ⚠️ | ❌ | ✅ |
Zero-latency now() |
❌ | ❌ | ❌ | ✅ |
License #
MIT License.
Credits #
Inspired by:
- Google Spanner TrueTime model
- NTP RFC 5905