I would like to measure elapsed time in a Java. However differences in System.currentTimeMillis()
and (I believe) System.nanoTime()
can be changed by external changes eg someone (or the system) altering the system clock.
Using network calls is not an option as it's possible very frequent and fast returns are required.
Is there a common solution for this?
EDIT
Sorry, I should have elaborated about the reason. It isn't to stop malicious users - it's things like client initiated logout for being idle and routine client events.
This doesn't really answer your question, but bug #6458294 implies that where possible, Sun's implementation of nanoTime() will use mechanisms which are truly monotonic (CLOCK_MONOTONIC on Linux, QueryPerformanceFrequency/QueryPerformanceCounter on Windows). Only if these are unavailable will it fall back to a mechanism which is susceptible to system clock changes.
If you have control (or at least knowledge) of the hardware you're running on, and can ensure that these clock mechanisms will be available, you might be in luck and nanoTime() will do fine.
You may also like to read this blog post, which discusses the HotSpot-on-Windows case in more detail.
I don't think there is a way to do this.
There is certainly no way to do this that cannot be subverted. Fundamentally, you are at the mercy of the operating system and the JVM as to what is reported to the Java app as the current time. Either or both of these could be patched so that the Java code ends up getting a bogus timestamp value. You could try to defend against this, but then all the hacker needs to do is to patch your app to disable license checking entirely.
For the record, this "vulnerability" applies whether or not you are using Java.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With