¿Cómo puedo medir el tiempo en Java no es susceptible a los cambios del reloj del sistema?

StackOverflow https://stackoverflow.com/questions/1937619

  •  20-09-2019
  •  | 
  •  

Pregunta

Me gustaría medir el tiempo transcurrido en un Java. Sin embargo las diferencias en System.currentTimeMillis() y (creo) System.nanoTime() se puede cambiar por los cambios externos por ejemplo, alguien (o el sistema) alterar el reloj del sistema.

El uso de llamadas de red no es una opción, ya que es posible se requieren las vueltas muy frecuentes y rápidos.

¿Hay una solución común para este?

Editar

Lo siento, debería haber elaborado sobre la razón. No es dejar de usuarios maliciosos. - Es cosas como cliente de cierre de sesión iniciada por ser eventos de cliente de inactividad y de rutina

¿Fue útil?

Solución

Esto en realidad no soluciona su problema, pero el bug # 6458294 implica que, cuando sea posible, la implementación de Sun de nanoTime () utilizará los mecanismos que son realmente monótona (CLOCK_MONOTONIC en Linux, QueryPerformanceFrequency / QueryPerformanceCounter en Windows). Sólo si éstos no están disponibles va a caer de nuevo a un mecanismo que es susceptible a los cambios del reloj del sistema.

Si usted tiene el control (o al menos conocimiento) del hardware se está ejecutando en, y puede asegurarse de que estos mecanismos de reloj estarán disponibles, es posible que en la suerte y nanoTime () hará muy bien.

También te puede interesar leer este post blog, que discute la HotSpot- caso de Windows con más detalle.

Otros consejos

No creo que hay una manera de hacer esto.

Ciertamente, no hay manera de hacer esto que no puede ser subvertido. Fundamentalmente, usted está a merced del sistema operativo y la JVM como a lo que se informa a la aplicación Java como la hora actual. Uno o ambos de estos podrían aplicar patches de modo que el código Java termina recibiendo un valor de marca de tiempo falso. Se podría tratar de defenderse de esto, pero entonces todo el hacker tiene que hacer es parchear su aplicación para desactivar la comprobación de licencia en su totalidad.

Para el registro, esta "vulnerabilidad" se aplica independientemente de si usted está utilizando Java.

Si usted está tratando de evitar que la gente subvertir un sistema de licencias ajustando el reloj de nuevo, es necesario almacenar el mayor tiempo que ha visto hasta ahora en algún tipo de almacenamiento cifrado y seguro y, a continuación, desactivar el programa si o bien el paso del tiempo inferior a la mayor que he visto (con algún margen para ajustes de reloj NTP y los cambios de horario de verano, por supuesto), o si de alguna manera alterar o eliminar el almacén seguro.

No sé si es probable que cambiar si cambia el reloj del sistema nanoTime (), pero supongo que es posible. También nanoTime () puede no ser exacta.

Si realmente necesita para protegerse contra cambios de reloj, se puede controlar el reloj en un hilo. El sueño durante 100 ms o 1000 ms, a continuación, llamar currentTimeMillis (). Si el reloj avanzó más de 1000 + xo ha ido hacia atrás entonces es probable que el reloj cambia (o el hilo quedó enganchado en algo, lo cual es posible).

En el caso de una disyunción, en realidad se podría hacer la llamada a la red para comprobar. Por supuesto, es posible que el tiempo de red puede cambiar debido a la inserción de saltar segundos . Una vez leí un comentario Slashdot por algunos científicos que estaba coordinando datos astronómicos de muchas fuentes diferentes. Un segundo salto se añadió durante su experimento, y que básicamente arruinó debido a que algunos sitios insertados y otros no.

Otra posibilidad podría ser el uso de una API nativa de bajo nivel para conseguir algunos otros temporizadores del sistema. Tal como sistema o disponibilidad de la red para calibrar el API. Windows tiene la función GetTickCount () que devuelve el número de milisegundos desde el inicio. En los sistemas UNIX puede utilizar el comando de tiempo de actividad para obtener una estimación aproximada. Puede comprobar periódicamente estos valores para ver si el reloj del sistema ha cambiado.

Si no te importa la adición de un poco de código nativo para su aplicación Java, utilice:

  • QueryPerformanceCounter() y QueryPerformanceFrequency() en Windows; o

  • función clock_gettime() POSIX con ID reloj CLOCK_MONOTONIC.

Tenga en cuenta que el uso de la X 86 TSC registrarse es desalentado en sistemas multiprocesador, así que es mejor utilizar las API anteriores.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top