DX라이브러리2014. 12. 30. 16:26

3.12 개조불가능한 세이브데이터 만드는법 - 1


지난 섹션에서 작성한 세이브파일은 바이너리에디터를 사용하면 간단하게 수정가능하다. 그렇다면 암호화를 통해서 수정하지 못하게 하면 어떨까 라는 생각이 들겠지만 사실 암호화는 필요하지 않다. 암호화 같은 복잡한 방법을 사용하지 않더라도 세이브파일이 수정되었는가 여부만 검사하면 되는 일이다. 일단 다음과 같이 세이브데이터를 텍스트로 보존한다고 가정하자.


HP = 200

MP = 100

소지금 = 1000

경험치 = 1000 


유저는 이 세이브파일을 열어 "경험치 = 2000" 이라고 수정했을 때 수정한 사실을 알고 있다면 게임에 적용하지 않으면 된다. 이는 해시값을 이용하여 구현 가능하다. 해쉬값은 해쉬함수를 통하여 구할 수 있으며 해시함수는 특정 계산식을 이용하여 특정값을 다른 값에 대응시키는 역할을 한다. 


HP = 200

MP = 100

소지금 = 1000

경험치 = 1000 


위에서 예를 들었던 데이터는 데이터 본체를 출력하고 있기 때문에 어딘가가 수정되어도 수정되었다는 것을 알 수 없다. 하지만 데이터의 마지막 부분에 아래와 같이 합계를 추가했다고 한다면 경험치 부분을 "경험치 = 2000"이라고 수정해도 합계와 맞지 않기 때문에 수정된 데이터라는 것을 알 수 있다.


HP = 200

MP = 100

소지금 = 1000

경험치 = 1000 

합계 = 2300


이 처럼 어딘가가 변경되면 함께 바뀌게되는 구조를 포함시키면 데이터 수정 여부를 검출 가능하다. 또한 아래와 같이 바이너리로 저장되어있다면 값이 변화할때마다 같이 변화하는 값이 별도로 존재한다고 상상하기 힘들것이다. 단, 데이터가 1:1대응이라면 이 역시 판독될 가능성이 매우 크다. 



최후에 기록되는 숫자를 합계가 아니라 합계에서 79로 나눈 수의 나머지라고 하고 이 값을 해시값이라고 가정해보자.


HP = 200

MP = 100

소지금 = 1000

경험치 = 2000 

해시값 = 61


위에서와 같은 데이터를 가지고 있을 때에 경험치를 2000에서 3000으로 변했다고 생각하면 합계 4300이며 79나누었을 때 나머지는 34가 된다.


HP = 200

MP = 100

소지금 = 1000

경험치 = 3000 

해시값 = 34


유저에게는 합계를 79로 나눈 나머지 라는 계산식을 알 수 없기 때문에 수정해보려고 해도 불가능 하게 된다. 어느 한부분이라도 값이 틀려지면 해시값과 맞지 않기 때문에 임의 수정되었는가 여부의 검출이 가능해진다. 또한 세이브 데이터를 이용하여 해시값의 계산은 가능해지지만 해시값을 이용한 세이브데이터의 역산도 불가능해진다.



이와 같이 역으로 계산 불가능한 해시 계산 방법을 단방향 해시라고 한다. 해시값의 계산 방법은 굉장히 많기 때문에 솔직히 말해 어떤 것을 사용하든 상관 없다. 탁 까놓고 말해 위에서 예로 들었던 79로 나눈 나머지값을 해시로 사용하는 것 만으로도 데이터의 임의 수정 가능성은 매우 낮아지게 된다. 하지만 유저들이 세이브데이터를 분석하여 마지막 4바이트의 값이 해시값이란것을 알게 된다면 1/79의 확률로 데이터 수정이 가능하게 된다. 때문에 보통 많이 사용하는 해시함수에는 "MD5", "SHA"등이 있다. 예를 들어 MD5는 128bit로 표현하는 함수이며 340282366920938463463374607431768211456종류의 해시값이 존재한다. 분석하려면 매우 큰 노력이 필요할 것이다. 다음 섹선에서는 MD5를 이용한 해시값 이용방법을 알아본다.

Posted by 캡슐리어