디컴파일을 방지하기 위해 컴파일된 Java 클래스를 잠그는 방법은 무엇입니까?

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

  •  09-06-2019
  •  | 
  •  

문제

디컴파일을 방지하기 위해 컴파일된 Java 클래스를 잠그려면 어떻게 해야 합니까?

나는 이것이 인터넷에서 매우 잘 논의되는 주제라는 것을 알고 있지만 그것을 참조한 후에는 어떤 결론도 내릴 수 없었습니다.

많은 사람들이 Obfuscator를 제안하지만 기억하기 어려운 문자 시퀀스를 사용하여 클래스, 메서드 및 필드의 이름을 바꾸는 작업만 수행하지만 민감한 상수 값은 어떻습니까?

예를 들어, 비밀번호 기반 암호화 기술을 기반으로 암호화 및 암호 해독 구성 요소를 개발했습니다.이제 이 경우 일반 Java 사용자라면 누구나 사용할 수 있습니다. 자드 클래스 파일을 디컴파일하고 비밀번호 값(상수로 정의됨)을 쉽게 검색할 수 있습니다. 소금 작은 독립 프로그램을 작성하여 데이터를 해독할 수 있습니다!

아니면 그러한 민감한 구성 요소를 네이티브 코드(예: VC++)로 구축하고 다음을 통해 호출해야 합니까? JNI?

도움이 되었습니까?

해결책

일부 고급 Java 바이트코드 난독처리기는 클래스 이름 맹글링 이상의 기능을 수행합니다. 젤릭스 클래스마스터, 예를 들어, 따라가기가 정말 어렵게 만드는 방식으로 코드 흐름을 뒤섞을 수도 있고 뛰어난 코드 최적화 도구로 작동할 수도 있습니다.

또한 난독 처리기 중 상당수는 문자열 상수를 뒤섞고 사용하지 않는 코드를 제거할 수도 있습니다.

또 다른 가능한 해결책(난독화를 반드시 배제할 필요는 없음)은 다음을 사용하는 것입니다. 암호화된 JAR 파일 그리고 해독을 수행하는 사용자 정의 클래스로더(바람직하게는 기본 런타임 라이브러리를 사용함).

세 번째(아마도 가장 강력한 보호 제공)는 다음과 같은 기본 사전 컴파일러를 사용하는 것입니다. GCC 또는 엑셀시어 제트, 예를 들어 Java 코드를 플랫폼별 기본 바이너리로 직접 컴파일합니다.

어쨌든 에스토니아어로 "자물쇠는 동물을 위한 것"이라는 속담을 기억해야 합니다.즉, 런타임 동안 모든 코드 비트를 사용할 수 있고(메모리에 로드됨) 충분한 기술, 결단력 및 동기 부여가 제공되면 사람들은 코드를 디컴파일하고 스크램블 해제하고 해킹할 수 있고 그렇게 할 것입니다.당신의 임무는 단순히 프로세스를 최대한 불편하게 만들고 계속 작동하도록 하는 것입니다...

다른 팁

암호화된 데이터와 이를 해독하는 소프트웨어 모두에 액세스할 수 있는 한 기본적으로 이를 완전히 안전하게 만들 수 있는 방법은 없습니다.이전에 이 문제를 해결한 방법은 동글, 원격 인증 서버 등과 같은 일종의 외부 블랙박스를 사용하여 암호화/복호화를 처리하는 것이었습니다.그러나 그럼에도 불구하고 사용자가 자신의 시스템에 대한 전체 액세스 권한을 갖고 있다는 점을 고려하면 이는 일을 어렵게 만드는 것이지 불가능한 것은 아닙니다. 예를 들어 온라인 게임 서버와 같이 "블랙 박스"에 저장된 기능에 제품을 직접 연결할 수 없다면 가능합니다. .

부인 성명:저는 보안 전문가가 아닙니다.

이것은 나쁜 생각처럼 들립니다.당신은 당신이 그에게 제공한 '숨겨진' 키를 사용하여 다른 사람이 물건을 암호화하도록 허용합니다.보안이 보장될 수 없다고 생각합니다.

어쩌면 비대칭 키가 작동할 수도 있습니다.

  • 공개 키로 암호화된 라이센스를 배포하여 해독합니다.
  • 고객이 새 라이센스를 생성하여 암호화를 위해 귀하에게 보내도록 합니다.
  • 새 라이센스를 클라이언트에 다시 보냅니다.

확실하지는 않지만 클라이언트가 실제로 귀하가 제공한 공개 키로 라이센스 키를 암호화할 수 있다고 믿습니다.그런 다음 개인 키로 암호를 해독하고 다시 암호화할 수도 있습니다.

실제로 올바른 고객으로부터 물건을 받고 있는지 확인하기 위해 고객별로 별도의 공개/개인 키 쌍을 유지할 수 있습니다. 열쇠에 대한 책임은...

무엇을 하든 '디컴파일'될 수 있습니다.헐 그냥 분해하면 됩니다.또는 메모리 덤프를 보고 상수를 찾으세요.컴퓨터가 이를 알아야 하므로 코드도 알아야 합니다.

이것에 대해 무엇을 해야 합니까?

코드에 하드코딩된 상수로 키를 제공하지 마세요.사용자별 설정으로 유지하세요.해당 키를 관리하는 책임은 사용자에게 있습니다.

@jatanp:또는 더 나은 방법은 디컴파일하고 라이센스 코드를 제거한 후 다시 컴파일할 수 있다는 것입니다.Java에서는 이 문제에 대한 적절하고 해킹 방지 솔루션이 실제로 존재하지 않는다고 생각합니다.Java에서는 사악한 작은 동글도 이를 막을 수 없습니다.

내 사업 관리자들은 이것에 대해 걱정하고 있으며 나는 생각이 너무 많습니다.그러나 우리는 라이센스 조건을 준수하는 경향이 있는 대기업에 애플리케이션을 판매합니다. 일반적으로 원두 판매점과 변호사 덕분에 안전한 환경입니다.라이센스가 올바르게 작성된 경우 디컴파일 자체를 하는 행위는 불법일 수 있습니다.

그래서 물어봐야겠네요. 당신은 그렇습니까? 정말 귀하의 애플리케이션을 찾고 있는 것처럼 강화된 보호가 필요합니까?귀하의 고객 기반은 어떤 모습입니까?(기업?아니면 10대 게이머 대중이 더 문제가 될까요?)

라이선스 솔루션을 찾고 있다면 다음을 확인해 보세요. TrueLicense API.이는 비대칭 키 사용을 기반으로 합니다.그러나 이것이 귀하의 응용 프로그램이 해독될 수 없다는 것을 의미하지는 않습니다.모든 애플리케이션은 충분한 노력을 기울이면 크랙될 수 있습니다.정말 중요한 것은 다음과 같습니다. 스투가 대답했다, 얼마나 강력한 보호가 필요한지 파악합니다.

효과적인 오프라인 불법 복제 방지 방법은 존재하지 않는다고 생각합니다.비디오 게임 산업은 여러 번 그들의 프로그램이 항상 깨졌음을 찾으려고 노력해 왔습니다.유일한 해결책은 라이센스 키를 확인할 수 있고 라이센스 사용자가 한 번에 하나의 활성 연결만 있도록 프로그램을 서버와 연결된 온라인으로 실행해야 한다는 것입니다.이것이 방법이다 월드 오브 워크래프트 또는 디아블로 공장.심지어 보안을 우회하기 위해 개발된 개인 서버도 있습니다.

그럼에도 불구하고 저는 중/대형 기업이 불법 복제 소프트웨어를 사용한다고 믿지 않습니다. 왜냐하면 이들 기업에 대한 라이센스 비용이 아주 적기 때문입니다(아마도 프로그램 비용이 얼마인지는 모르겠습니다). 평가판 비용.

걱정 없이 바이트 코드 암호화를 사용할 수 있습니다.

사실 위에서 인용한 논문 "Java 바이트 코드 암호화 크래킹"에는 논리 오류가 포함되어 있습니다.논문의 주요 주장은 다음과 같다. 실행하기 전에 모든 클래스의 암호를 해독하여 전달해야 합니다. ClassLoader.defineClass(...) 방법.그러나 이것은 사실이 아니다.

여기서 놓친 가정은 단, 인증된 표준 Java 런타임 환경에서 실행되어야 합니다..보호되는 Java 앱이 이러한 클래스를 시작할 뿐만 아니라 이를 해독하여 전달하도록 의무화할 수 있는 것은 없습니다. ClassLoader.즉, 표준 JRE에서는 가로채기가 불가능합니다. defineClass(...) 표준 Java에는 이 목적을 위한 API가 없기 때문에 패치가 적용된 수정된 JRE를 사용하는 경우 ClassLoader 또는 다른 "해커 트릭"은 보호된 Java 앱이 전혀 작동하지 않기 때문에 수행할 수 없으며 따라서 가로챌 수 있는 것이 없습니다.그리고 어떤 "패치 파인더"가 사용되는지 또는 해커가 어떤 트릭을 사용하는지 전혀 중요하지 않습니다.이러한 기술적 세부 사항은 상당히 다른 이야기입니다.

큐:.class 파일을 암호화하고 사용자 정의 클래스 로더를 사용하여 즉시 로드하고 해독하면 디컴파일이 방지됩니까?

ㅏ:Java 바이트 코드 역컴파일을 방지하는 문제는 언어 자체만큼이나 오래되었습니다.시장에 나와 있는 다양한 난독화 도구에도 불구하고 초보 Java 프로그래머는 자신의 지적 재산을 보호하기 위한 새롭고 기발한 방법을 계속해서 생각합니다.이번 Java Q&A 기사에서는 토론 포럼에서 자주 재탕되는 아이디어에 대한 몇 가지 오해를 풀어보겠습니다.

Java .class 파일을 원본과 매우 유사한 Java 소스로 매우 쉽게 재구성할 수 있다는 점은 Java 바이트 코드 설계 목표 및 장단점과 많은 관련이 있습니다.무엇보다도 Java 바이트 코드는 컴팩트성, 플랫폼 독립성, 네트워크 이동성 및 바이트 코드 해석기 및 JIT(Just-In-Time)/HotSpot 동적 컴파일러를 통한 분석 용이성을 위해 설계되었습니다.컴파일된 .class 파일은 프로그래머의 의도를 명확하게 표현하므로 원래 소스 코드보다 분석하기가 더 쉬울 수 있습니다.

디컴파일을 완전히 막지는 못하더라도 최소한 디컴파일을 더 어렵게 만들기 위해 여러 가지 조치를 취할 수 있습니다.예를 들어 컴파일 후 단계에서 .class 데이터를 마사지하여 바이트 코드를 디컴파일할 때 읽기 어렵게 만들거나 유효한 Java 코드로 디컴파일하기 어렵게 만들 수 있습니다(또는 둘 다).극단적인 메소드 이름 오버로딩을 수행하는 것과 같은 기술은 전자에 적합하고 제어 흐름을 조작하여 Java 구문을 통해 표현할 수 없는 제어 구조를 생성하는 것은 후자에 적합합니다.보다 성공적인 상업용 난독 처리기는 이러한 기술과 다른 기술을 혼합하여 사용합니다.

불행하게도 두 접근 방식 모두 JVM이 실행할 코드를 실제로 변경해야 하며 많은 사용자는 이러한 변환으로 인해 애플리케이션에 새로운 버그가 추가될 수 있다는 점을 두려워합니다(당연히 그렇습니다).또한 메서드 및 필드 이름을 바꾸면 리플렉션 호출이 작동을 중지할 수 있습니다.실제 클래스 및 패키지 이름을 변경하면 여러 다른 Java API(JNDI(Java Naming and Directory Interface), URL 공급자 등)가 손상될 수 있습니다.변경된 이름 외에도 클래스 바이트 코드 오프셋과 소스 줄 번호 간의 연결이 변경되면 원래 예외 스택 추적을 복구하는 것이 어려울 수 있습니다.

그런 다음 원본 Java 소스 코드를 난독화하는 옵션이 있습니다.그러나 이는 근본적으로 유사한 문제를 야기합니다.난독화하지 않고 암호화하시겠습니까?

아마도 위의 내용을 통해 "바이트 코드를 조작하는 대신 컴파일 후 모든 클래스를 암호화하고 JVM 내에서 즉석에서 해독하면 어떻게 될까요(사용자 정의 클래스 로더를 사용하여 수행 가능)?"라고 생각하게 되었을 수도 있습니다.그런 다음 JVM이 내 원래 바이트 코드를 실행하지만 디컴파일하거나 리버스 엔지니어링할 내용이 없습니다. 맞죠?"

불행하게도 당신은 이 아이디어를 처음 생각해냈다고 생각하는 것과 그것이 실제로 효과가 있다고 생각하는 것 모두 틀렸을 것입니다.그리고 그 이유는 암호화 체계의 강도와는 아무런 관련이 없습니다.

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