Unity에서 플레이어로부터 끈을 완전히 숨기고 보호하는 방법은 무엇입니까?


47

나는 Unity를 사용하여 완전히 오프라인 (문제) 인 2D 게임을 만들었습니다. 게임 플레이는 특정 레벨에서 특정 문자열을 입력하고 Unity는 DLL로 컴파일해야하므로 쉽게 리버스 엔지니어링 할 수 있습니다. 그 문자열을 보호하는 방법이 있습니다 (게임이 오프라인이므로 다른 소스에서 검색 할 수 없습니다)?

이 게임은 그 줄에 크게 의존하고 있습니다. 예. 난독 화에 대해 알고 있지만 더 강력한 것을 원합니다. 그리고 쉬운 방법은 데이터 소스에서 온라인으로 모든 것을 수행하는 것이지만 가능한지 궁금합니다.

다음과 같이 디 컴파일 할 수 있습니다. 여기에 이미지 설명을 입력하십시오


10
나는 그것이 당신이 진정으로 이길 수없는 싸움이라는 것에 동의하지만, 적은 노력으로 확실히 더 힘들게 만들 수 있습니다. obfuscar.codeplex.com
Jacob Persi

46
@Gabriele Huh? 난독 화되지 않은 C # 코드를 디 컴파일하는 것은 쉽게 얻을 수 있습니다. 그런 식으로 코드를 완벽하게 읽을 수 있으며, IDA가 최적화 된 C 또는 C ++ 코드를 위해 생성하는 것과 비교할 수 있습니다. 그것은 충분한 노력으로 네이티브 코드를 이해할 수는 있지만 수십 배가 더 어렵다고 말했습니다. 난독 화가 얼마나 잘 작동하는지 잘 모릅니다. 일반적인 디 컴파일러 (DotPeek, ILSpy, 그 밖의 다른 것)가 일리노이 코드를 방해하지 않도록 방해하는 IL 코드를 만들면 말입니다.
Voo

15
@GabrieleVierti, DLL에서 텍스트를 가져 오는 것은 쉽지 않습니다. Linux 나 Cygwin에서는 strings프로그램을 가리 키기 만하면됩니다 .
Mark

31
여기서 정확히 무엇을하려고합니까? 이것은 XY 문제의 다소 심각한 경우처럼 들립니다. meta.stackexchange.com/questions/66377/what-is-the-xy-problem (기술적 인 관점이 아닌 게임 플레이 관점에서) 달성하려는 것이 무엇이든 이러한 문자열을 숨기고 암호화하려고 시도하는 것이 최선의 방법은 아닙니다. .
GrandOpener

36
문자열을 숨기는 것이 실제로 목적에 부합하는지 궁금합니다. 일부 플레이어가 문제를 해결하면 Wiki 또는 이와 유사한 형태로 퍼질 가능성이 높으므로 알고 싶어하는 사람은 누구나 쉽게 검색 할 수 있습니다. 네, 그것들을 난독 화함으로써 플레이어는 텍스트 편집기에서 dll을 열고 문자열을 찾을 수는 없지만 대부분 Google (또는 선택한 검색 엔진)을 먼저 상담합니다 ...
hoffmale

답변:


160

해당 문자열을 저장하지 말고 (암호화) 해시를 저장하십시오.

암호화와 같은 (암호화) 해시 함수는 문자열을 "기괴한"(해시라고 함)로 바꾸는 방법이지만 암호화와 달리이 해시에서 원래 문자열을 가져올 수 없습니다 (무차별 적으로 또는 해시를 사용하지 않는 한) 기능이 끊어졌습니다). 대부분의 (전부는 아님) 해시 함수는 임의 길이의 문자열을 가져와 일정한 길이의 문자열을 반환합니다 (함수에 따라 다름).

사용자가 입력 한 문자열이 올바른지 어떻게 확인합니까? 해시에서 유효한 문자열을 얻을 수 없기 때문에 사용자의 추측을 해시하고 올바른 해시와 비교하는 것이 유일한 방법입니다.

경고 (Eric Lippert 제공) : 내장 함수 GetHashCode를 이러한 함수 로 사용하지 마십시오. 결과는 .NET 버전과 플랫폼마다 다를 수 있으므로 코드는 특정 .NET 프레임 워크 버전 및 플랫폼에서만 작동합니다.


81
이것이 실제로 가장 좋은 대답입니다. 그러나 문자열에 기본적으로 내장 해시 알고리즘을 사용해서는 안된다는 것을 명심하십시오 . 그것은 오직 한가지 일만을하도록 설계되었으며 그것은 해시 테이블의 균형을 맞추는 것입니다. .NET 런타임 작성자는 어떤 이유로 든 실제로 해시 알고리즘을 변경할 권한이 있기 때문에 문자열 해시를 저장하고 공유 비밀의 인증 자로 사용할 수 없습니다 . 암호화 강도 표준 해시를 사용하거나 간단한 해시를 구현하십시오.
Eric Lippert

4
이. 바로 그거죠. sha256과 같은 알고리즘을 사용하면 (이를 구현하는 많은 라이브러리가 있으므로 직접 작성할 필요가 없습니다) 쉽게 깨지지 않으며 매우 신뢰할 수있는 무언가가 있습니다.
Micheal Johnson

12
@Michael Johnson은 솔트를 사용하면 레인보우 테이블을 사용하기가 훨씬 어려워지고 bcrypt와 같은 암호 해시를 사용하면 훨씬 느리게 깨지기가 어려워집니다. 그러나 결국 하루가 끝날 무렵에는 너무 많은 노력이 필요한 것 같습니다. 사용자가 자신의 선택 인 컨닝을 원한다면 게임을 구입했습니다
Melkor

2
@MichealJohnson : 키 스트레칭 은 이러한 무차별 대입 공격을 조금 더 어렵게 만들 수 있습니다 (예 : 10 억 정도 정도). 그러나이 답변의 실제 문제는 아마도 어떤 시점에서 게임이 플레이어에게 입력 해야하는 문자열을 알려줄 수 있어야한다는 것입니다. 그 줄이 실제로 플레이어가 해결해야 할 퍼즐에 대한 해결책이 아니라면, 나는 추측합니다. 또는 게임이 오프라인 상태 인 경우에도 문자열이 온라인으로 제공되지 않으면 구식 라이센스 키와 비슷합니다.
Ilmari Karonen

5
@Sentinel 이는 플레이어마다 게임 플레이가 다를 수 있음을 의미합니다. 게임에서 책 / 표지판 / 대화 상자에 포함되어 있거나 실제 답변이 플레이어에게 직접 제공되지 않는 퍼즐에 대한 해결책이라면, 어떤 종류의 문자열을 이야기해야하는지 알아야합니다. 또는 무작위로 생성 된 경우. 그리고 단어, 문장 또는 임의의 문자 인 경우.
Micheal Johnson

106

당신이하려는 것은 쓸데없고 무의미합니다.

사용자 컴퓨터에있는 정보를 제대로 숨길 수있는 방법이 없기 때문에 쓸모가 없습니다. 충분히 헌신 한 사람이면 찾을 수 있습니다. 더 어렵게 만들 수는 있지만 결코 막을 수는 없습니다. 암호화하면 암호화 키와 알고리즘을 어딘가에 저장해야합니다. 추가 한 암호화 계층 수에 관계없이 게임을 실행하려면 항상 최상위 계층을 암호화 해제해야합니다.

우리는 인터넷 시대에 살고 있기 때문에 무의미합니다. 게임이 원격으로 인기를 얻으면 해당 암호가 웹 전체에 게시됩니다.

당신이 할 수있는 일은 게임이 아직 그들에게 말하지 않은 정보를 찾아 자신의 게임 경험을 망치지 않도록 플레이어를 신뢰하는 것입니다. 어쨌든 대다수의 플레이어는 게임을 리버스 엔지니어링하지 않습니다. 그리고 필요한 기술을 가진 소수의 사람들이 이것을한다면, 그것은 자신의 잘못입니다.


38
리버스 엔지니어링은 자체 게임입니다! 이것은 유일한 정답입니다. 요즘 싱글 플레이어 게임에서 정보를 숨기면 안되며, 원하는 경우 플레이어가 정보에 액세스합니다.
Mephy

27
@TheBinaryGuy 무엇으로부터의 안전? 사용자가 오프라인 게임을하고 있습니다. 코드 노출에 어떤 위협이 있습니까? 플레이어는 결국 게임을 할 수 있도록 그것을 발견해야합니다! 보안의 중요한 규칙 은 보호 대상을 식별 해야 한다는 것입니다 . 이것을 "위협 모델"이라고합니다.
jpmc26

7
@TheBinaryGuy 다른 점들 외에도, "고정 된"암호를 사용하는 감수성에 의문을 제기했습니다. 온라인 / 역 공학을 통해 코드를 조회하지 않아도 게임을 다시 한 번만하면 플레이어가 바로 건너 뛸 수 있습니다. 게임의 섹션 (이미 코드를 알고 있음). 플레이어가이 코드를 획득하도록 "강제로"하려면 각 플레이 스루마다 변경해야합니다 (예 : 임의의 형태의 무작위 화)
UnholySheep

6
이 답변에는 몇 가지 좋은 점이 있지만 두 번째 단락은 올바르지 않습니다. 문자열을 암호화하지 않아도됩니다. 해시 할 수 있습니다. 플레이어가 해시를 깨뜨릴 수 있다면 대신 은행 계좌를 강탈하거나 FBI에 의해 고용 될 것입니다. 다른 점은 유효합니다.
Pedro A

5
@ Hamsterrific 대답은 실제 문자열을 저장해야한다고 가정합니다. 예를 들어 어떤 시점에서 플레이어에게 문자열을 표시하려면 해시가 수행되지 않습니다.
프랭크 홉킨스

4

그러한 것이 실제로 필요한 경우 해싱 대신 런타임에 숫자 입력 값에서 문자열을 작성하는 것을 고려할 수 있습니다.

장점은 @Philipp이 지적한 것처럼 어쨌든 인터넷에 게시 될 것으로 예상되는 경우 실행 파일에서 코드를 숨기려고 시도하는 것이 다소 의미가 없다는 것입니다. 해시 여부에 상관없이 인터넷에서 발견되어 게임에 입력 된 동일한 단어가 동일한 해시를 제공하며 어느 쪽이든 작동합니다.

... 제외하는 것은 제외하고 누군가 다른 사람의 코드는 경우 작동하지 않습니다 당신을 위해. 100 % 변조 방지가 아니라 일반 사용자를 위해 합리적으로 해결하기가 쉽지 않습니다. "Online Elven 이름 생성기"처럼 간단한 작업도 가능합니다 (임의적으로 간단 할 수 있습니다. 실제로 임의의 목록에서 4-5 음절을 가져 오는 것으로 충분한 markov 텍스트 생성 엔진이 필요하지 않습니다).

사용자 별 또는 컴퓨터 별 번호를 생성하기 만하면 완벽하게 고유하거나 조작 방지 기능이 없어도됩니다. 컴퓨터의 네트워크 이름, MAC 주소 또는 시스템 디스크 드라이브의 GUID와 같이 대부분의 사람들에게 다를 수 있고 정기적으로 변경되지 않는 것 (GPU 일련 번호가 매우 나쁠 수 있음)사용자가 GPU를 업그레이드 할 가능성이 있기 때문에 아이디어). 잠금 해제 코드가 참조하는 숫자 코드를 단어 생성기에 추가하십시오. 그러나 플레이어가 두 대의 컴퓨터를 사용하거나 네트워크 카드를 변경하는 경우 지원 쿼리에 응답 할 수 있도록 준비하십시오 (이례적이지만 불가능하지는 않음). 랜덤 ID를 한 번만 생성하고 게임 설정과 함께 저장하는 것이 좋습니다. 이런 식으로, 최소한 변경 사항이있을 경우 동일한 시스템에서 기존 설치를 중단하지 않습니다.

또는 사용자가 하드웨어를 변경하면 고유 한 게임 일련 번호를 사용할 수도 있습니다 (그러나 아이러니하게도 공유 잠금 해제 코드는 불법 복제 된 일련 번호에는 작동하지만 합법적 인 고객에게는 적용되지 않기 때문에 불법 복제를 유발할 수 있습니다).

사용자의 부정 행위를 방지하는 것이 반드시 좋은 것은 아닙니다. 오프라인 (즉, 비 경쟁적 게임)에서는 사용자 가 게임을하는 대신 어딘가 에서 부정 행위를하고 코드를 가져 오더라도 문제가되지 않습니다 . 그는 자신을 속이고 있습니다. 누가 신경 쓰겠 어?
반면에, 실제로 속임수를 쓰고 싶다면 너무 많은 돈을 버는 것은 유료 고객 을 완전히 화나게 할 수있는 좋은 기회입니다 .

그러니까 ... 그렇게하기 전에 정말 원하는지, 원하는지를 철저히 생각하십시오. 아마도 사람이 읽을 수있는 문자열 (또는 xor로 "읽을 수없는"문자열)을 만드는 것만으로도 충분하고 실제로 선호됩니다.


어떤 프로세스를 계획하고 있습니까? 프로그램이 다운로드 후 해시 값을 생성하는 경우 다운로드시 해시되지 않은 문자열이 있어야합니다. 서버가 클라이언트에게 정보 식별을 요청한 다음 해시 서버 측을 생성합니까?
누적

@Acccumulation : 어떤 서버? Q는 "완전히 오프라인"이라고 말합니다. DVD의 프로그램 (또는 다운로드)에 일련 번호를 더한 것일 수 있습니다. 따라서 암호가 있어야하는 이벤트 1,2,3,4가 있습니다. 예 hash(serial + 1)를 들어 첫 번째 코드에 해당하는 숫자를 얻기 위해 계산 합니다. 그런 다음 단어 생성기에 입력하면 4 비트 입력마다 16 개의 목록에서 한 음절을 가져옵니다. 모든 사용자를위한 개별 "단어"가 있습니다.
Damon

다운로드 인 경우 서버에서 다운로드중인 것입니다. 프로그램 이 다운로드 된 hash(serial+1) 계산하는 경우 사용자가 계산하지 못하게하려면 어떻게해야 hash(serial+1)합니까? 프로그램이 다운로드되면 사용자는 프로그램이하는 모든 것에 액세스 할 수 있습니다.
누적

@ 누적 : 사용자가 먼저 프로그램을 디 컴파일 한 다음 계산 하는 것을 막을 수있는 것은 없습니다 hash(serial + 1). 그래서 무엇? 이것은 문제가되지 않습니다. 누군가가 1 ~ 2 시간 (소프트웨어 개발자 배경이없는 일반적인 "사용자"의 경우 6 ~ 8 시간)을 투자하여 자신을 속이는 경우에 .. 문제는 한 사람에게는 효과가 있지만 모든 사람에게는 효과가 없으며 경쟁력이 없기 때문에 문제 없습니다.
데이먼

3

문자열을 보여줄 필요가 없다면, 해싱 아이디어는 아마도 갈 길입니다. 반면에 사용자에게 표시해야하는 경우 DLL에서 직접 표시되지 않도록 할 수있는 다른 방법이 있습니다.

문자열을 암호화하거나 난독 처리하는 것 외에 이것을 처리하는 한 가지 방법은 문자열을 분리하는 것입니다. 어쩌면 게임의 모든 문자열에서 가능한 모든 단어를 사전 순으로 알파벳순으로 정렬했을 수도 있습니다. 그런 다음 단어 배열로 인덱싱하여 필요한 문자열로 단어를 묶을 수있는 어딘가에 배열을하십시오. 이런 식으로 게임의 어느 곳에서나 완벽한 문자열을 얻을 수 없습니다. 문자열을 해독하는 데 필요한 마스터 키가 없습니다. 예를 들어 문자열을 사용하는 각 함수에 함수에 대한 인덱스 배열이 있으면 순서를 알려주는 데이터가 소스 전체에있을 수 있습니다. 나는 그것이 당신의 특정한 경우에 얼마나 실용적인지 잘 모르겠지만, 그것을하는 한 가지 방법입니다.

문자열을 몇 단어로 구성했을 수도 있지만 결국 순서가 다릅니다. 예를 들어 다음 두 문자열이 필요할 수 있습니다.

  1. 곰이 내 집을 걸었다
  2. 내 집은 곰에서 나를 보호

문구 목록에는 "곰"과 "내 집"이 모두 포함되어 있지만 그 사이에 넣을 수있는 다른 문구 목록이 많으므로 실제로 알아내는 것만 큼 어려운 문구를 알아낼 수 있습니다. 게임의 퍼즐 (또는 무엇이든). 예를 들어, 액션 문구는 "통과", "번 다운", "밀어 넣은", "보호 된 사람", "분리 된 사람", "마 법적으로 제작 된"등이 될 수 있습니다.

플레이어가 수집하거나 수행 한 것을 기반으로 인덱스를 만들어 게임에서이 작업을 수행 할 수 있습니다. 따라서 게임 내부에는 인덱스의 마스터 목록이 없습니다. 게임을하는 플레이어가 생성합니다.


4
따라서 특정 문자열을 참조하는 함수를 찾는 대신 인덱스가있는 배열을 참조하는 함수를 찾은 다음 문자열을 다시 작성하십시오. 30 초 이상의 보호 기능은 아닙니다. 그것이 보호하는 것은 실행 가능한 사람에 대해서만 사용 strings하는 것입니다.
Voo

내가 말했듯이 문자열을 참조하는 배열이 필요한 모든 함수에 분산되면 단일 함수에서 단일 배열을 찾는 것보다 조금 어렵습니다. 불가능하지는 않지만 많은 추가 작업없이 넓은 지역을 커버합니다.
user1118321 2018

이것이 단순한 형태의 암호화가 아닙니까?
Arturo Torres Sánchez

2
잠깐만, 암호화조차도. 인코딩 만하면됩니다.
Arturo Torres Sánchez

2
더 명확하게 답변을 업데이트했습니다. 기본적으로 인덱스가 플레이어가 수행 한 작업을 기반으로하는 경우 실제로 게임에 저장되지 않습니다. 다시 말하지만, 그것은 완벽하지는 않지만 완벽하지는 않지만 사람들이 탐색하고 싶은 옵션으로 여기에 넣었습니다.
user1118321
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.