无任何网络连接时如何验证设备日期未被篡改且准确有效?
可行方案说明
首先要明确:完全无任何网络/基站授信的前提,不存在100%获取不可篡改绝对准确日期的通用方案,但是可以通过几个低复杂度的方案把风险降到你要求的安全级别,几乎不会误扰正常用户:
方案1:使用不可篡改的运行时长做时间基准(推荐,实现成本极低)
这个方案可以解决99%的日常场景需求:
- Android端的开机运行时长可以通过
SystemClock.elapsedRealtime()接口获取,iOS端可以通过[NSProcessInfo processInfo].systemUptime获取,两个值都用户无法手动修改,设备重启后会清零,不受系统日期修改的影响。 - 你只需要在应用每次能拿到可信时间(联网同步NTP、或者确认系统已完成网络时间同步)时,同时记录两个值到本地存储:
- 当时的可信时间戳
trusted_ts - 当时的系统开机运行时长
recorded_uptime
- 当时的可信时间戳
- 后续无网络需要获取时间时,直接用公式计算准确时间:
当前可信时间 = trusted_ts + (当前系统uptime - recorded_uptime) - 只要设备没有重启,不管用户怎么修改系统日期、开关飞行模式,该计算结果都是完全准确的。
方案2:补充校验重启后基准丢失的场景
如果用户重启设备后第一次打开应用时无网络,你可以通过两个轻量校验规则规避风险:
- 如果当前系统时间早于你上次应用正常退出时记录的可信时间,直接判定系统时间无效,提示用户需要联网完成一次时间同步后再使用
- 如果当前系统时间晚于上次记录的可信时间,你可以对比时间差和两次记录的运行时长累计差值,如果二者偏差超过24小时(正常运行场景下偏差不会超过1分钟),再触发联网校验提示,正常无网区域使用的用户完全不会被误拦截
特殊场景说明
如果用户是首次安装应用,第一次打开就完全无网络,也没有任何历史可信时间基准,这种场景没有任何技术方案可以获取准确日期,属于物理限制。你可以针对这类场景做首次启动的弱引导,只要求用户首次打开应用时有一次网络连接完成时间初始化,后续就可以完全离线正常使用。
内容的提问来源于stack exchange,提问作者user2638180
相关产品推荐
相关产品推荐

