시스템 시계 변경에 취약하지 않은 Java의 시간을 어떻게 측정 할 수 있습니까?

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

  •  20-09-2019
  •  | 
  •  

문제

자바에서 경과 시간을 측정하고 싶습니다. 그러나 차이 System.currentTimeMillis() 그리고 (나는 믿는다) System.nanoTime() 시스템 클록을 변경하는 다른 사람 (또는 시스템) (또는 시스템)에 의해 변경 될 수 있습니다.

네트워크 호출을 사용하는 것은 매우 빈번하고 빠른 반환이 필요하기 때문에 옵션이 아닙니다.

이것에 대한 일반적인 해결책이 있습니까?

편집하다

죄송합니다. 이유에 대해 자세히 설명해야합니다. 악의적 인 사용자를 멈추는 것은 아닙니다. 클라이언트가 유휴 상태이고 일상적인 클라이언트 이벤트가되는 로그 아웃과 같은 것입니다.

도움이 되었습니까?

해결책

이것은 실제로 당신의 질문에 대답하지는 않지만 버그 #6458294 가능한 경우 Sun의 Nanotime () 구현은 진정으로 단조로운 메커니즘을 사용한다는 것을 암시합니다 (Linux의 Clock_Monotonic, Windows의 QueryPerformanceFrequency/QueryPerformancecounter). 이것들을 사용할 수없는 경우에만 시스템 클록 변경에 취약한 메커니즘으로 돌아갑니다.

실행중인 하드웨어에 대한 제어 (또는 최소한 지식)가 있고 이러한 시계 메커니즘을 사용할 수있게되면 운이 좋을 수 있으며 Nanotime ()이 잘 작동 할 수 있습니다.

당신은 또한 읽는 것을 좋아할 수도 있습니다 이 블로그 게시물, 핫스팟 온 윈도우 케이스에 대해 자세히 설명합니다.

다른 팁

나는 이것을 할 방법이 없다고 생각합니다.

분명히이를 수행 할 수있는 방법은 없습니다. 기본적으로, 당신은 현재 시간으로 Java 앱에보고 된 내용에 대해 운영 체제와 JVM의 자비에 있습니다. Java 코드가 가짜 타임 스탬프 값을 얻을 수 있도록 이들 중 하나 또는 둘 중 하나 또는 둘 다 패치 될 수 있습니다. 당신은 이것에 대해 방어하려고 시도 할 수 있지만, 해커가해야 할 일은 앱을 패치하여 라이센스 점검을 완전히 비활성화하는 것입니다.

레코드의 경우,이 "취약성"은 Java를 사용하고 있는지 여부에 관계없이 적용됩니다.

시계를 다시 설정하여 사람들이 라이센스 제도를 전복하는 것을 막으려 고하는 경우, 지금까지 보았던 가장 높은 시간을 암호화하고 안전한 스토리지에서 가장 많이 저장 한 다음 시간이면 프로그램을 비활성화해야합니다. 보았던 최고 (NTP 시계 조정 및 DST 변경에 대한 허용량과 물론 DST 변경 사항) 또는 보안 상점을 조작하거나 삭제하는 경우 가장 높은 것으로 나타납니다.

시스템 시계가 변경되면 Nanotime ()이 변경 될 가능성이 있는지 모르겠지만 가능하다고 생각합니다. 또한 Nanotime ()은 정확하지 않을 수 있습니다.

실제로 시계 변경에 대비 해야하는 경우 스레드의 시계를 모니터링 할 수 있습니다. 100ms 또는 1000ms의 수면 후 CurrentTimeMillis ()를 호출하십시오. 클럭이 1000 + x보다 더 많이 전진되거나 뒤로 이동 한 경우 시계가 변경 될 가능성이 높습니다 (또는 스레드가 무언가에 매달려 가능합니다).

분리 된 경우 실제로 네트워크 호출을 확인하여 확인할 수 있습니다. 물론 삽입으로 인해 네트워크 시간이 변경 될 수 있습니다. 도약 초. 나는 한때 많은 다른 출처에서 천문 데이터를 조정 한 일부 과학자들의 슬래시 도트 의견을 읽었습니다. 그의 실험 중에 도약 한 두 번째가 추가되었고, 일부 사이트는 그것을 삽입했고 다른 사이트는 그렇지 않았기 때문에 기본적으로 그것을 망쳤습니다.

또 다른 가능성은 낮은 레벨 네이티브 API를 사용하여 다른 시스템 타이머를 얻는 것입니다. API를 보정하기위한 시스템 또는 네트워크 가동 시간과 같은. Windows에는 getTickCount () 함수가있어 부팅 후 밀리 초 수를 반환합니다. UNIX 시스템에서는 Uptime 명령을 사용하여 대략적인 추정치를 얻을 수 있습니다. 이 값을 정기적으로 확인하여 시스템 시계가 변경되었는지 확인할 수 있습니다.

Java 앱에 약간의 기본 코드를 추가하는 것이 마음에 들지 않으면 다음을 사용하십시오.

  • QueryPerformanceCounter() 그리고 QueryPerformanceFrequency() 창에서; 또는

  • posix clock_gettime() 기능 CLOCK_MONOTONIC 시계 ID.

x86의 사용 TSC 레지스터 멀티 프로세서 시스템에서 낙담하므로 위의 API를 사용하는 것이 좋습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top