【问题标题】:Is there any way to check a date is correct (under no tampering attempt) without any connectivity?有没有任何方法可以在没有任何连接的情况下检查日期是否正确(在没有篡改尝试的情况下)?
【发布时间】:2021-10-15 14:11:57
【问题描述】:

我正在开发一个应用程序,我可以使用new Date() 在多个地方检索当前日期,我希望如果用户更改了手机中的日期,则不允许使用它的日期错了。

由于应用程序的性质,当获取日期的操作完成时,可能没有互联网连接,因此我们可以越来越少地确保如果用户有选项使用网络日期/时间和使用网络时区,并且他可以连接到电话网络,那么日期是正确的(当然,如果可以篡改日期,但它看起来足够安全)。

问题是也有可能没有使用电话的电话网络,我检查了以下内容:

  1. 您可以禁用使用网络日期/时间并设置您喜欢的日期。

  2. 您激活了飞行模式(或类似的无连接情况)

  3. 你重启手机。

  4. 您启用使用网络日期/时间。

现在,尽管设置了使用网络日期/时间和使用网络时区,但手机上的日期不正确。确实,如果我退出飞行模式,日期会再次正确设置。

也许可以通过检查用户是否已重新启动手机的服务,然后在手机启动时再次正确地确定日期的服务来检测类似以前的情况,因此应用程序会检查该服务是否表明它已正确使用,因此它允许用户使用它...但这一切似乎很难做到,我们可能会打扰诚实的用户,他们必须在没有电话连接的区域中重新启动手机,然后尝试使用该应用程序而不尝试欺骗其他日期。

那么,对于一个不太复杂的方法和诚实的用户没有窃听,可以在没有任何类的连接的情况下获取日期的任何想法?或者这是不可能的?

【问题讨论】:

  • 什么是correct 日期?如果我在几秒或几毫秒内退出会发生什么?您可能不是在寻找正确的日期,而是在寻找一个范围
  • 是的,只要不是我昨天应该做的手术,但我今天没有做,但设置为昨天的日期就可以了。
  • 我想第一次开始不是使用new Date(),而是获取格林威治标准时间的日期/时间。这样,您已经解决了更改时区作弊的人的问题。您还可以存储上次使用该应用程序的时间。有了它,您可以禁用过去的作弊。对于未来的作弊,我没有看到简单的解决方案。
  • 您唯一能做的并避免这些问题,就是与服务器时间同步。然后,在这样做之后,有一个简单的方法可以确定。

标签: java android date


【解决方案1】:

为了在 Java 中获取系统时间,您可以使用 System.currentTimeMillis(),尽管此模块与电话时间和日期同步。为了获得与手机日期和时间无关的系统时间,您可以使用System.nanoTime(),它与手机时钟无关。

但是,nanoTime 模块不是绝对的——它是相对于某个任意点进行测量的,因此您应该在代码中保存一些 nanoTime 的值,它是一个已知日期,然后进行比较。

this 文章中了解如何格式化从nanoSeconds 到日期的时间。

关于nanoTime的相关文章。

【讨论】:

    【解决方案2】:

    你在说

    System.currentTimeMillis(). 
    // user can change it by adjusting the DATE of the phone.
    

    但这可以帮助你。

    SystemClock.elapsedRealtime()
    

    这两者之间的区别可以帮助你。

    https://developer.android.com/reference/android/os/SystemClock

    • 编码后,您应该将毫秒转换为日期

    【讨论】:

      【解决方案3】:

      没有仅离线解决方案可以满足“我怎么知道用户没有将日期更改为错误日期”的标准。

      您唯一能做的并避免这些问题,就是与服务器时间同步。然后,在这样做之后,有一个简单的方法可以确定。

      您想使用 SystemClock.elapsedRealtime()(每次启动后都会重置,并且需要新的服务器时间同步)

      类似的东西:

      public class DeviceTimeProvider {
      
          public long getElapsedRealtimeMillis() {
              return SystemClock.elapsedRealtime();
          }
      
          public long getCurrentTimeMillis() {
              return System.currentTimeMillis();
          }
      }
      
          public TimeSnapshot createTimeSnapshot() {
              long upTime = deviceTimeProvider.getElapsedRealtimeMillis();
              long clock = deviceTimeProvider.getCurrentTimeMillis();
              String bootId = bootIdProvider.getBootId();
      
              return new TimeSnapshot(upTime, clock, bootId);
          }
      
       . . .
      
      public class TimeSnapshot {
      
          public final long upTime;
          public final long clockTime;
          public final String bootId;
      
          public TimeSnapshot(long upTime, long clockTime, String bootId) {
              this.upTime = upTime;
              this.clockTime = clockTime;
              this.bootId = bootId;
          }
      . . .
      }
      
      public class BootIdProvider {
          private final Context context;
          private String cachedBootId = null;
      
          public BootIdProvider(Context context) {
              this.context = context;
          }
      
          public String getBootId() {
              if (cachedBootId != null) {
                  return cachedBootId;
              }
      
              String bootId = null;
      
              if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
                  try {
                      bootId = String.valueOf(Settings.Global.getInt(context.getContentResolver(),
                              Settings.Global.BOOT_COUNT));
      
                  } catch (Settings.SettingNotFoundException e) {
                      LFLog.w(LOG_TAG, "", e);
                  }
              } else {
                 // try reading "proc/sys/kernel/random/boot_id" or just do this
                 bootId = UUID.randomUUID().toString();
              }
      
              cachedBootId = bootId;
              return bootId;
          }
      }
      

      但请确保每次启动时至少与服务器时间同步一次(一次即可),不管这些,因为其他任何东西都可以用来欺骗您。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-01
        • 1970-01-01
        • 2019-05-21
        • 1970-01-01
        • 1970-01-01
        • 2020-12-01
        相关资源
        最近更新 更多