2016-07-29 2 views
3

이것은 메모리 데이터 보안 문제입니다.
자바 가비지 수집은 가비지 데이터를 안전하게 지 웁니 다?가비지 수집은 가비지 데이터를 안전하게 지 웁니까?

데이터 청크가 가비지 수집 된 후에는 더 이상 검색 할 수 없지만 해커가 여전히 데이터를 검색하기 위해 메모리 덤프를 할 수 있습니까?

+0

관련 항목 : http://stackoverflow.com/questions/8881291/why-is-char-preferred-over-st-for-passwords-in-java – shmosel

+0

메모리 보안은 어렵습니다. 누군가 휴대 전화로 데이터를 스캔하여 데이터를 검색하면 휴대 전화에서 대부분의 보안 정보를 얻을 수 있습니다. 스토리지 및 전송 중 데이터를 안전하게 보호하는 데 더 많은 노력을 기울일 수 있습니다. –

+0

걱정되는 HIPAA 준수입니다. HIPAA 준수에 메모리 암호화가 필요한지 여부는 확실하지 않습니다. –

답변

2

이것은 JVM 구현 및 가능한 옵션에 따라 다르지만 데이터를 지우지 않을 것이라고 가정합니다. 가비지 콜렉션은 사용 가능한 영역 만 추적하면됩니다. 모든 데이터를 0 또는 다른 것으로 설정하는 것은 불필요한 많은 쓰기 작업입니다. 이러한 이유로 API에서 String 대신 암호 배열을 사용하는 경우가 자주 있습니다.

+0

char 배열은 공격 성공 확률 만 감소 시키지만 전체 제거를 보장하지는 않습니다. –

+0

@AndrewLygin Right. 나는 또한 자신이 배열을 지울 필요가 있다고 언급하지 않았다. 메모리 덤프에서 내용을 읽지 못하게하는 배열에 대한 본질적인 것은 없습니다. – JimmyJames

+0

불행히도 여기에는 상황이 좀 더 복잡해지며 수동으로 데이터를 지우는 것이 항상 완벽하게 제거되는 것은 아닙니다. 자세한 내용은 내 대답을 참조하십시오. –

0

특히 Oracle JVM은 공간을 지우지 않으며 Eden과 Survivor 공간 사이의 데이터 만 복사합니다. 더 이상 사용되지 않는 오브젝트는 결국 덮어 쓰레기로 남아 있습니다. OldGen에서 비슷한 일이 일어나고, 일부 장소는 사용 된 것으로 표시되고, 오브젝트가 가비지 콜렉션에 적합하게되면 점유 한 곳은 사용되지 않는 것으로 표시됩니다. 충분한 응용 프로그램 시간이 주어지면 덮어 쓰여진 eventaully도 덮어 씁니다.

+0

Oracle JVM은 일반적인 Java VM입니까? 저는 Android 앱 데이터 보안에 더 관심이 있습니다. –

+0

@LiwenZhao Android (또는 Dalvik/ART)는 JVM이 아니므로 JVM에서 아무것도 적용 할 수 없습니다. 질문에'android'로 주석을 달아주세요. 오라클은 JVM, 참조 구현입니다. –

4

여기에 언급 된 다른 사용자와 마찬가지로 JVM은 가비지 수집 후에 메모리를 안전하게 지우지 않습니다. 성능이 크게 나빠질 수 있기 때문입니다. 그래서 많은 프로그램 (특히 보안 라이브러리)은 불변 (문자열 대신 char 배열) 대신 변경 가능한 구조를 사용하고 더 이상 필요없는 경우 데이터 자체를 정리합니다.

불행히도 그러한 접근법이 항상 작동하지는 않습니다. 이 시나리오를 살펴 보겠습니다.

  1. 암호로 문자 배열을 만듭니다.
  2. JVM은 가비지 콜렉션을 수행하고 문자 배열을 메모리의 다른 위치로 이동 시키며 이전에 메모리가 차지했던 메모리는 그대로두고 그대로 빈 블록으로 표시합니다. 이제 비밀번호의 '더티 복사본'이 생겼습니다.
  3. 암호로 작업을 마쳤으며 모든 문자가 안전하다고 생각하는 문자 배열의 모든 문자를 명시 적으로 0으로 설정했습니다.
  4. 공격자가 메모리 덤프를 만들고 2 단계
나는이 문제에 대한 하나의 가능한 솔루션 생각할 수

전에, 그것은 처음 배치 된 메모리에 암호를 찾습니다

  1. G1 가비지 컬렉터를 사용하십시오.
  2. G1에서 사용하는 영역 크기의 절반 이상을 차지할만큼 충분히 큰 단일 블록 (기본 값 배열)을 만드십시오 (기본적으로이 크기는 최대 힙 크기에 따라 다르지만, 수동으로 지정하십시오.) 그러면 콜렉터가 데이터를 소위 '거대한 대상'으로 취급해야합니다. 이러한 객체는 G1 GC가 메모리에서 이동하지 않습니다.
  3. 그런 경우 블록의 일부 데이터를 수동으로 지울 때 힙 어딘가에 동일한 데이터의 다른 '더티 복사본'이 없는지 확인할 수 있습니다.

다른 해결책은 원하는대로 수동으로 처리 할 수있는 오프 힙 데이터를 사용하는 것이지만 순수 Java는 아닐 것입니다.

+0

Go에서는 순수한 Go를 사용하여 syscall을 사용하여 커널 (mmap/virtualalloc 등)에서 직접 메모리를 요청할 수 있습니다. Java에서 이와 유사한 것이 가능한지 확실하지 않습니다. – Awn

관련 문제