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


96

디 컴파일을 방지하기 위해 컴파일 된 Java 클래스를 어떻게 잠그나요?

나는 이것이 인터넷에서 매우 잘 논의 된 주제 임에 틀림 없다는 것을 알고 있지만 그것들을 참조한 후에는 어떤 결론에 도달 할 수 없었다.

많은 사람들이 obfuscator를 제안하지만 기억하기 어려운 문자 시퀀스로 클래스, 메서드 및 필드의 이름을 변경하지만 민감한 상수 값은 어떻습니까?

예를 들어, 암호 기반 암호화 기술을 기반으로 암호화 및 암호 해독 구성 요소를 개발했습니다. 이제이 경우 모든 일반 Java 사용자는 JAD 를 사용 하여 클래스 파일을 디 컴파일하고 솔트 뿐만 아니라 암호 값 (상수로 정의 됨)을 쉽게 검색 할 수 있으며, 작은 독립 프로그램을 작성하여 데이터를 해독 할 수 있습니다!

또는 이러한 민감한 구성 요소를 네이티브 코드 (예 : VC ++)로 빌드하고 JNI 를 통해 호출해야 합니까?


어쨌거나 분해 된 네이티브 코드조차도 일부 사람들이 읽을 수 있지만, 명확하지 않게 만들기 위해 난독 화 자나 손으로 만든 어셈블리를 사용해야 할 것입니다 (최적화로 컴파일 된 일반적인 C ++는 충분히 읽을 수 있음). 사용자의 장치에서 실행되는 모든 코드를 가로 챌 수 있습니다. 이러한 가로 채기의 비용 / 기술 요구 사항은 상당히 높을 수 있지만, 예를 들어 스마트 카드 "변조 방지"칩 코드에 침입하는 것은 사소한 것이 아니라 최고의 장비와 기술로만 수행 할 수 있습니다. Java 클래스를 사용하면 ...별로 신경 쓰지 않을 것입니다. 스크립트를 사용하지 않도록 암호화 할 수있을 것입니다.
Ped7g

답변:


96

고급 자바 바이트 코드 난 독기 중 일부는 단순한 클래스 이름 변경 이상의 기능을 수행합니다. 예를 들어, Zelix KlassMaster 는 코드 흐름을 따라 가기가 정말 어렵게 만들고 훌륭한 코드 최적화 프로그램으로 작동하는 방식으로 코드 흐름을 뒤섞을 수도 있습니다.

또한 많은 obfuscator는 문자열 상수를 스크램블하고 사용하지 않는 코드를 제거 할 수 있습니다.

또 다른 가능한 솔루션 (난독 화를 반드시 제외 할 필요는 없음)은 암호화 된 JAR 파일 과 암호 해독을 수행하는 사용자 정의 클래스 로더를 사용하는 것입니다 (가급적 네이티브 런타임 라이브러리 사용).

세 번째 (그리고 아마도 가장 강력한 보호 기능을 제공함)는 GCC 또는 Excelsior JET 와 같은 기본 사전 컴파일러를 사용하는 것 입니다. 예를 들어 Java 코드를 플랫폼 별 기본 바이너리로 직접 컴파일합니다.

어쨌든 당신은 에스토니아어 "자물쇠는 동물을위한 것"이라는 속담을 기억해야합니다. 즉, 런타임 동안 모든 코드를 사용할 수 있고 (메모리에로드 됨) 충분한 기술, 결정 및 동기 부여가 주어지면 사람들이 코드를 디 컴파일, 스크램블 및 해킹 할 수 있고 그렇게 할 것입니다. 여러분의 임무는 프로세스를 다음과 같이 불편하게 만드는 것입니다. 당신은 여전히 ​​일을 계속할 수 있습니다 ...


13
"자물쇠는 동물을위한 것"에 +1. 여기에 적절한 용어는 대본 키디 일 것입니다.
Antimony

당신은 GCJ를 의미하고 그것은 죽었습니다.
Marquis of Lorne

1
Componio jar 파일 암호화도 죽었습니다. 대신 JarProtector 를 사용하십시오 .
J.Profi

16

암호화 된 데이터와이를 해독하는 소프트웨어에 모두 액세스 할 수있는 한 기본적으로이를 완벽하게 보호 할 수있는 방법은 없습니다. 이전에이 문제를 해결 한 방법은 동글, 원격 인증 서버 등과 같은 암호화 / 복호화를 처리하기 위해 외부 블랙 박스를 사용하는 것입니다.하지만 사용자가 자신의 시스템에 대한 전체 액세스 권한을 가지고 있다는 점을 감안할 때 어렵고 불가능하지는 않습니다. 온라인 게임 서버와 같이 "블랙 박스"에 저장된 기능에 제품을 직접 연결할 수 없다면.


13

면책 조항 : 저는 보안 전문가가 아닙니다.

이것은 나쁜 생각처럼 들립니다. 누군가에게 당신이 제공 한 '숨겨진'키로 물건을 암호화하게합니다. 나는 이것이 안전 할 수 있다고 생각하지 않는다.

비대칭 키가 작동 할 수 있습니다.

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

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

당신은 당신이 실제로 바로 고객에서 물건을 받고 만들기 위해 고객 당 별도의 공개 / 개인 키 쌍을 유지할 수 - 지금 당신은 키에 대한 책임이 있습니다 ...


2
이전에이 기술을 사용해 보았는데 잘 작동합니다. 그러나 공격 관점에서 첫 번째 접근 방식은 라이선스 확인을 수행하는 코드를 수정하고 제거하는 것입니다. 이 공격 벡터를 더 어렵게 만들 수있는 방법이 있지만 공격자에게 하드웨어 제어 권한을 부여하면 적절하게 동기를 부여하고 숙련 된 공격자가 실패 할 수 있습니다. 실제로 목표는 가장 정직한 사람들을 정직하게 유지하는 것입니다.
Jim Rush

12

무엇을하든 '디 컴파일'될 수 있습니다. 그냥 분해하면됩니다. 또는 상수를 찾기 위해 메모리 덤프를보십시오. 컴퓨터가 그것들을 알아야하기 때문에 여러분의 코드도 알아야합니다.

이것에 대해 어떻게해야합니까?

키를 코드에서 하드 코딩 된 상수로 제공하지 마십시오. 사용자 별 설정으로 유지하십시오. 사용자가 해당 키를 관리하도록합니다.


6

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

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

그래서 나는 당신이 당신의 응용 프로그램을 찾고있는 것처럼 정말로 강화 된 보호가 필요합니까? 고객 기반은 어떻게 생겼습니까? (기업? 아니면 10 대 게이머 대중, 어디가 더 문제가 될까요?)


실제로 btw가 동글처럼 보이는 적절한 해킹 방지 솔루션이 있습니다. excelsior-usa.com/blog/excelsior-jet/…
Dmitry Leskov

@DmitryLeskov '해킹 방지', 아마도. 그러나 그것은 코드를 원하는 사람에게는 속도 범프 일뿐입니다. 하루가 끝나면 바이트 코드는 암호화되지 않은 호스트 플랫폼에서 실행되어야합니다. 마침표.
Stu Thompson

내가 링크 한 게시물을 읽지 않았습니다. 바이트 코드는 동글의 CPU 코드 로 변환 되고 암호화됩니다. 최종 사용자가 보호 된 앱을 실행하면 암호화 된 코드가 "동글"로 전송됩니다. 동글은 CPU에서 암호를 해독하고 실행합니다.
Dmitry Leskov 2013-08-10

2
기업 십대 게이머.
odiszapc

3

라이선스 솔루션을 찾고 있다면 TrueLicense API를 확인할 수 있습니다 . 비대칭 키 사용을 기반으로합니다. 그러나 애플리케이션이 크랙 될 수 없다는 의미는 아닙니다. 모든 애플리케이션은 충분한 노력으로 크랙 될 수 있습니다. 정말 중요한 것은 Stu가 대답 했듯이 귀하에게 얼마나 강력한 보호가 필요한지 파악하는 것입니다.


2

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

그렇긴하지만 중대형 기업이 불법 복제 소프트웨어를 사용한다고 생각하지 않습니다. 라이선스 비용이 적기 때문입니다 (아마도 프로그램에 대해 얼마나 많은 비용을 청구해야하는지 모르겠습니다). 평가판 비용.


2

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

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

여기에서 놓친 가정은 그들이 진짜 또는 표준 자바 런타임 환경에서 실행되고 있다는 가정 입니다 . 보호되는 Java 앱이 이러한 클래스를 시작하는 것뿐만 아니라 해독하고 ClassLoader. 즉, 표준 JRE에있는 defineClass(...)경우 표준 Java에는 이러한 목적을위한 API가 없기 때문에 메서드를 가로 챌 수 없으며 , 패치 된 JRE ClassLoader또는 기타 "해커 트릭" 과 함께 수정 된 JRE를 사용하는 경우 보호되기 때문에 수행 할 수 없습니다. Java 앱은 전혀 작동하지 않으므로 가로 챌 것이 없습니다. 그리고 어떤 "패치 파인더"가 사용되는지 또는 해커가 어떤 트릭을 사용하는지는 절대적으로 중요하지 않습니다. 이러한 기술적 세부 사항은 완전히 다른 이야기입니다.


패치 된 JVM을 정확히 어떻게 감지 하시겠습니까? 어쨌든,이 모든 일은 일을 약간 더 어렵게 만드는 것입니다.
Antimony

앱 시작 관리자에서 defineClass () 호출을 찾을 수 없습니까? 그 호출을 할 때 어쨌든 해독 된 바이트 배열을 전달해야합니다. 원래 소스가 유출 될 수있는 또 다른 지점이 아닙니까?
Ascendant 2013

4
나는이 답변에 정말로 동의하지 않습니다. 나에게 이것은 "질문 : Pi를 찾는 가장 쉬운 방법은 무엇입니까? 대답 : 2 * Pi를 2로 나누십시오."와 같이 들립니다. 나는 아이디어에 동의하지 않지만 더 자세한 내용을 포함 할 수 있습니까? 예를 들어, 메인 프로그램이 순수 자바로 작성되기를 기대하십니까? 수정하려는 코드가 포함되어 있습니까?
Patrick M

-1

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

A : 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이 내 원래 바이트 코드인데도 디 컴파일이나 리버스 엔지니어링이 필요하지 않습니다. "

불행히도, 당신이이 아이디어를 가장 먼저 떠 올렸다고 생각하고 그것이 실제로 효과가 있다고 생각한다면 당신은 틀렸을 것입니다. 그리고 그 이유는 암호화 체계의 강도와 관련이 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.