You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Android平台下可靠计算时间差及事件时间上报方案问询

可靠的Android事件时间戳上报方案(防客户端时间篡改)

针对你提到的「用Java.Date实现事件时间戳上报易被客户端时间篡改」的问题,我给你一套完全规避这个风险的方案——核心是不依赖本地系统时间,改用设备的单调计时器计算流逝时间,结合服务器同步的基准时间生成真实事件戳。

核心逻辑

问题根源在于Java.Date依赖本地系统时间,用户随便改一下时间,从同步到事件的流逝时间计算就完全错了。而我们要用不受系统时间修改影响的单调时钟(设备开机后的累计运行时间)来算时间差,再加上服务器给的基准Posix Time,就能得到绝对可靠的事件时间戳。

分步实现

1. 启动时同步服务器基准时间

应用启动后,先向服务器拿当前的秒级Posix Time,同时记录下此时设备的elapsedRealtime(这个值是从设备开机到现在的毫秒数,用户改系统时间、时区都不会动它)。

  • 要加重试机制,确保同步成功;如果网络差同步失败,可以缓存上次成功的同步数据,或者触发事件时先重新同步。

示例代码:

// 启动时执行的同步逻辑
private void syncServerTime() {
    // 调用你的服务器接口,获取当前秒级Posix时间
    long serverPosixTime = yourApi.fetchCurrentPosixTime();
    // 记录同步时的单调计时起点
    long syncElapsedMillis = SystemClock.elapsedRealtime();
    
    // 把这两个值存在安全的地方,比如加密后的SharedPreferences
    saveSyncData(serverPosixTime, syncElapsedMillis);
}

2. 事件触发时计算真实时间戳

当用户点击按钮(事件发生)时,别碰本地Date,按下面步骤算:

  1. 获取当前的elapsedRealtime
  2. 算出从同步到事件的流逝毫秒数
  3. 转成秒后加到服务器基准时间上,就是事件的真实Posix时间戳

示例代码:

button.setOnClickListener(v -> {
    // 取出之前保存的同步数据
    long serverPosixTime = getSavedServerPosixTime();
    long syncElapsedMillis = getSavedSyncElapsedMillis();
    
    // 计算流逝时间
    long currentElapsedMillis = SystemClock.elapsedRealtime();
    long elapsedSeconds = (currentElapsedMillis - syncElapsedMillis) / 1000;
    
    // 生成真实事件时间戳
    long eventPosixTime = serverPosixTime + elapsedSeconds;
    
    // 上报给服务器
    yourApi.reportEvent(eventPosixTime);
});

3. 额外的可靠性优化

  • 定期重新同步elapsedRealtime在设备重启后会重置,所以重启后必须重新同步;另外,长时间运行后单调计时的微小误差会累积,建议每隔1-2小时重新同步一次。
  • 处理同步失败场景:如果事件触发时还没同步成功,先把事件缓存起来,等同步完成后再补上报;也可以上报时附带当前的elapsedRealtime和本地系统时间(仅供服务器参考校验)。
  • 加密存储同步数据:把同步的时间数据存在SharedPreferences时,最好加密,防止用户通过修改存储文件伪造时间。
  • 处理计时溢出SystemClock.elapsedRealtime()long类型,设备连续运行约292年才会溢出,日常使用基本不用考虑,但如果是长期运行的IoT设备,可以在同步时记录溢出次数。

为什么这个方案靠谱?

SystemClock.elapsedRealtime()是基于硬件的单调递增计时器,完全独立于系统时间——哪怕用户把本地时间改成10年前或者10年后,从同步到事件的流逝时间计算依然精准,最终的事件时间戳完全基于服务器的基准时间,根本没法被客户端篡改影响。

内容的提问来源于stack exchange,提问作者Exprove

火山引擎 最新活动