Comment puis-je mesurer le temps en Java inaltérables aux changements d'horloge du système?

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

  •  20-09-2019
  •  | 
  •  

Question

Je voudrais mesurer le temps en Java. Toutefois, les différences dans System.currentTimeMillis() et (je crois) System.nanoTime() peut être modifié par des changements externes, par exemple une personne (ou le système) modifiant l'horloge du système.

L'utilisation des appels du réseau ne sont pas une option car il est possible des rendements très fréquents et rapides sont nécessaires.

Y at-il une solution commune pour cela?

EDIT

Désolé, j'ai élaboré la raison. Il ne faut pas empêcher les utilisateurs malveillants -. Ce sont des choses comme client initié la déconnexion pour être des événements clients inactifs et de routine

Était-ce utile?

La solution

Cela ne répond pas vraiment à votre question, mais bug # 6458294 implique que lorsque cela est possible, la mise en œuvre de NanoTime () Sun utilisera les mécanismes qui sont vraiment monotones (CLOCK_MONOTONIC sur Linux, QueryPerformanceFrequency / QueryPerformanceCounter sous Windows). Seulement si ceux-ci ne sont pas disponibles va retomber à un mécanisme qui est sensible aux changements d'horloge du système.

Si vous avez le contrôle (ou au moins la connaissance) du matériel que vous utilisez, et peut assurer que ces mécanismes d'horloge seront disponibles, vous pourriez être de la chance et NanoTime () fera très bien.

Vous pouvez également lire ce billet de blog , qui traite de la HotSpot- cas sur Windows plus en détail.

Autres conseils

Je ne pense pas qu'il y ait une façon de le faire.

Il n'y a certainement aucun moyen de faire ce qui ne peut pas être subverti. Fondamentalement, vous êtes à la merci du système d'exploitation et la machine virtuelle Java à ce qui est rapporté à l'application Java comme l'heure actuelle. Ou les deux d'entre eux pourraient être patché afin que le code Java finit par obtenir une valeur d'horodatage bogus. Vous pouvez essayer de se défendre contre cela, mais tout le pirate doit faire est de patcher votre application pour désactiver complètement la vérification de licence.

Pour mémoire, cette « vulnérabilité » applique si vous utilisez Java.

Si vous essayez d'empêcher les gens de subvertir un système de licence en réglant l'horloge en arrière, vous devez stocker le plus de temps que vous avez vu jusqu'à présent dans une sorte de stockage crypté et sécurisé, puis désactiver le programme si soit le temps passe moins le plus élevé que vous avez vu (avec une provision pour ajustements d'horloge NTP et les changements d'heure d'été bien sûr), ou si elles falsifier ou supprimer une certaine façon avec le magasin sécurisé.

Je ne sais pas si NanoTime () est susceptible de changer si les changements d'horloge du système, mais je suppose que cela est possible. En outre NanoTime () peut ne pas être exacte.

Si vous avez vraiment besoin de se prémunir contre les changements d'horloge, vous pourriez surveiller l'horloge dans un fil. Sommeil pour 100ms ou 1000ms, puis appelez currentTimeMillis (). Si l'horloge avance plus de 1000 + x ou a reculé alors probablement changé l'horloge (ou le fil se est accroché sur quelque chose, ce qui est possible).

En cas de disjonction, vous pouvez réellement faire l'appel pour vérifier le réseau. , Il est bien sûr possible que le temps de réseau pourrait changer en raison de l'insertion de sauter secondes . J'ai lu un commentaire Slashdot par certains scientifiques qui coordonnait les données astronomiques de beaucoup de sources différentes. Un deuxième saut a été ajouté au cours de son expérience, et essentiellement en ruine parce que certains sites insérés et d'autres ne l'ont pas.

Une autre possibilité pourrait être d'utiliser une API native de bas niveau pour obtenir d'autres minuteries du système. Un tel système ou la disponibilité du réseau pour calibrer l'API. Windows a la fonction GetTickCount () qui retourne le nombre de millisecondes depuis le démarrage. Sur les systèmes Unix, vous pouvez utiliser la commande de disponibilité pour obtenir une estimation approximative. Vous pouvez vérifier périodiquement ces valeurs pour voir si l'horloge du système a changé.

Si vous ne me dérange pas d'ajouter un peu de code natif à votre application Java, utilisez:

  • QueryPerformanceCounter() et QueryPerformanceFrequency() sous Windows; ou

  • fonction POSIX clock_gettime() avec l'ID d'horloge CLOCK_MONOTONIC.

Notez que l'utilisation du x86 TSC s'inscrire est découragée sur les systèmes multiprocesseurs, vous utilisez mieux les API ci-dessus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top