안드로이드 인앱 결제 시스템에 대해서 가이드를 꾸역꾸역 따라가다 보면
결국 보안에 대해서 명시한 글을 만나게 됩니다.
(가이드 : http://developer.android.com/guide/google/play/billing/index.html)
아래 링크를 보시면 이런 글이 있습니다.
http://developer.android.com/guide/google/play/billing/billing_best_practices.html
Protect your Google Play public key
To keep your public key safe from malicious users and hackers, do not embed it in any code as a literal string. Instead, construct the string at runtime from pieces or use bit manipulation (for example, XOR with some other string) to hide the actual key. The key itself is not secret information, but you do not want to make it easy for a hacker or malicious user to replace the public key with another key.
골자는 코드상에 리터럴 상수로 때려 박을경우 보안에 취약하니 서버를 통해서 내려 받거나 적어도 XOR로 퍼블릭키를
숨겨서 사용하라..
훌륭한 가이드 아닙니까??? 보안에 취약하니깡 안내 문구도 명시해주고 말입니다.
그래서 서버가 없는 제 경우에 이 퍼블릭 키를 숨기기 위해서 머리를 굴려봤습니다.
C로 키를 한번 XOR해서 퍼블릭키와 XOR키를 숨겼습니다.
그리고 사용시에 다시 복원해서 사용했습니다.
하지만.... 별 의미 없습니다.
왜냐하면 네이티브에서 바로 서버와 인증을 하는경우가 아니니 때문에 ..
결국 java로 올려야 합니다.
이게 무슨의미냐면 패킹된 어플을 뒤집어 까서 so 파일을 끄집어 낸다음에
navtive 함수를 호출하면 결과를 볼 수 있으니 raw 폴더에 넣는거나 별반 차이 없습니다.
so파일을 호출해도 xor 된 값이라 java에서 복원하는 루틴을 알아내야 하겠지요 그래서
이를 막기위해서 난독화 해서 어플 보는걸 방해 하면 되겠지요.. 하지만 완벽하지 않습니다.
그럼 어케 하느냐?
서버 사용해야 됩니다. 라는 결론밖에 생각이 안나는군요..ㅠㅠ
서버도 완벽하지 않겠지만.. 서버를 사용하면 퍼블릭키 변수가 바인딩 되는시점이
동적으로 최대한 느슨하게 되고 .. 패킹되어 있어 코드상에 노출되는 경우가 아니므로 이를 알아내려면 메모리를 덤프 뜨거나
인터넷에서 내려오는 패킷정보를 후킹하거나 해야 하는데 이정도 하는놈들이 제 어플에 관심을 가지면 답이 없겠지요.
그래도 서버만한게 없어 보이네요 ㅋㅋ
한마디로 결국 서버..ㅠㅠ
지난번에도 글 올렸다 시피.. data/data 영역을 지울 수 있는 기능때문에 내장에 저장한 데이터가 보존될 수 없다고
해서 결국 서버 써야 된다고 말햇는데 ..
에전에 올린글..
http://www.androidpub.com/index.php?mid=devfree&page=6&document_srl=2213522
이 문제에 대해서 해결방안이나 좋은 생각있음 공유좀 부탁드려요 ~!!
인앱 결제는 잘 몰라서 뭐라 하기 좀 거시기 하지만...
퍼블릭 키를 숨겨야 하는 이유가 있나요? 퍼블릭인디... 그냥 이름에서 느껴지는 건 공개잖아요. ^^;;;
보통 암호화에서 공개키(퍼블릭 키)는 노출되고, 개인키(프라이빗 키)는 감추잖아요.
위에 있는 영어 문구대로라면 퍼블릭 키는 비밀이 아니지만, 해커가 다른 퍼블릭 키로 교체하지 못하도록 하는 것이 필요하다... 인데요
코드에 퍼블릭 키를 스트링 그대로 넣으면 당연 다른 스트링으로 교체해 버릴 수가 있겠죠.
하지만 코드 상에는 스트링이 적혀 있지 않다면 이걸 알아낼 수는 있어도 교체할 수 있는 수단은 없어 보입니다.
그냥 구글이 하라는데로 하는게..
런타임 상에서 값을 조합해서 만들어낼 수 있게끔요
맨 처음 키를 아무거나 복잡하게 만들구요
sha-256 으로 해시를 뜬 다음 3번째 글자를 public key 의 첫 글자로 넣고
또 이 글자를 이전 해시값에 append 시켜서 해시값을 만들고 여기서 17번째 글자를 public key 의 두번쨰 글자로 넣고..
이런 식으로 해서 public key 를 실행 중에 완성(?)하면 그나마 좀 괜찮지 않을까요?
적어도 코드 상으로 읽어서 해시값을 계산해 낼 천재는 없으니까요ㅋ
물론 3번째 17번째라는건 그냥 제가 임의로 얘기한거고
개발자가 public key 에 맞게 일일이 돌려보면서 수작업으로 맞춰야겠죠ㅎ
저 같으면 이 문제 때문에 서버까지 만드는건... 아마 최후의 보루로 갈거 같습니다.
public key 자체가 알려진다고 해서 보안에 엄청 피해가 생기는 것도 아니니까요.
이름부터가 퍼블릭인걸요ㅎ
위에 언급한 내용이 최대한 바인딩 시점을 늦춰서 해도...
감출수 없다는 내용입니다.
key = "alkdjglkajgaijglkjzxkjeoijg" 이렇게 하면 컴파일 이전에 바인딩이 되는거고..
key = loadKey(); 이렇게 하면 런타임이 되겠지요..
so 파일에 감추어도 결국 호출단계에 이르러 복원되는 루틴만 알면 노출되는겁니다.
복원을 막고자 프로가드 하지만.. 자바의 언어 특성상... 노출을 막을수 없으리라 생각됩니다. (제 추측이지만^^)
아래는 난독화에 대해서 좀더 강하게 할 수 있는 방법에 대해서 누군가 포워딩 한 내용입니다.
http://www.androidpub.com/2196533
난독화 잘하고 해쉬알고리즘까지 사용하면 진짜 잘 숨긴거겠지요?ㅎㅎ
음... 어떤 식으로 해도 숨길 수는 없습니다. APK를 깐 다음 그대로 돌려보면 나오니까요. 서버를 사용한다고 하더라두요. 서버에서 접근을 막지 않는 이상. 서버 접근은 어떻게 막을까요?
말씀하신 링크에 들어가 보니 RSA라고 되어 있네요. 그렇다면 공개키로 암호화 해서 보낸다는 뜻인데, 어차피 개인키 모르면 해독을 못합니다. 개인키는 구글 서버에 있겠죠.
근데 문제는 뭔가 메시지를 공개키로 암호화해서 보내면 그걸 구글 서버에서 개인키로 해독해서 처리할텐데요
제가 해커라면 메시지와 공개키를 교묘하게 수정해서 구글 서버에서 해독시 다른 메시지로 해독되도록 하겠습니다.
(근데 사실 개인키를 모르는 상태에서 이걸 하려면 굉장히 어렵습니다. 저는 못할 듯 ^^;;; 이건 미친 짓인듯)
근데 이렇게 하려면 APK 내에 박혀 있는 스트링을 수정해야 할텐데 APK 내에 스트링이 박혀 있지 않다면???
제가 보기엔 XOR로 스트링을 박아 넣는 것 또한 위험해 보입니다. 스트링을 교체할 수 있다면 XOR 쯤이야...
그래서 APK 내에 스트링 박아 넣는 것 자체를 하지 않으면 될 듯.
Add your public key to the following line of code:
String base64EncodedPublicKey = "your public key here";
이부분 이야기 하나보네요.
스트링을 박어 넣으라고 되어있네요 ^^
어제 회사에서 구글 플레이에 유료 어플로 올렸습니다.
LVL적용해서 올렸는데 단 하루 만에 크랙버전이 돌아 다녀서
리버싱 한결과 LVL에서는 정상적으로 인증을 거쳐서 들어옵니다.
apk파일 키싸인이 변경된것으로 보아 안에 코드를 삽입하고 다시 패킹한듯 했습니다. (정확하지는 않습니다.)
사이트는 지금 폐쇠되었고요..
유료버전을 내리고 무료버전으로 다시 올렸습니다.
비지니스모델이 바뀌었습니다. 광고 + 인앱으로 안드로이드는 무족건 갑니다.
완전 굴욕이죠..회사에서 가뜨기나 안드로이드 바보취급하는데 바보 맞구나 하는 생각밖에 안듭니다.
하긴 iOS도 크랙되는 판국에 ㅋㅋ
그래서 인앱빌링 부분 보안에 대해서 신경쓰고 있습니다. 그나마...... 안전하길 바라면서..
아래 동영상은 크랙되는 동영상인데 이게 진짜일까요?
http://www.youtube.com/watch?v=ZiWJzC_jwxA
http://www.dailymotion.com/video/xpqu1g_how-to-remove-licence-verification-of-android-apps-rooted-mobile_tech
구글 검색어로 google in app billing crack version 이렇게 쓰면
나오는 싸이트는 뭘까요?
진짜라면 어케했을까나..되게 궁금허냉..
퍼블릭키에 대해서 잘 설명되어 있군요.. 이거 보면 그냥 때려 박아도 될까? 싶기도 하지만..
크랙버전이 버전이 굴러다니고 있다고 생각하면 조금 노력을 기울이는게
월급 먹고 자리지키는 저로써는 해야 할 도리가 아닌가 싶기도 하네요..
하지만 귀찮음이 밀려오고 있는뎅..ㅠㅠ
http://dooeui.blogspot.kr/2010/06/blog-post_23.html
http://www.sersc.org/journals/JSE/vol9_no1_2012/11.pdf
아즈라엘님 화나셨나봐요. ^^;;;
음..... 쉽게 생각하는 건 아니구요... 아무리 머리를 굴려봐도 뾰족한 수가 안 나와서...
NDK로 하든, 서버에서 받든, 복잡한 알고리즘을 돌리든, 난독화를 무지막지하게 하든
제가 생각할 때는 마음만 먹으면 다 알아낼 수 있을 것 같거든요.
하루만에 크랙되다니... 무서운 세상이군요.
이렇다는 말은 그냥 무식하게 해킹하는 것이 아니라 툴이 있거나 방법론이 있다는 것인데
문제가 심각하네요. 어찌어찌해서 퍼블릭 키를 잘 감춘다고 해도 안될 것 같아서요.
왜냐하면 이렇게 빨리 해킹한다는 것은 퍼블릭 키를 몰라도 뚫는 방법이 있다는 생각이 들거든요.
구글의 인앱빌링 자체가 패턴이 있을테니까 이 패턴 자체를 공격하는 것 같다는 생각이 문득 드네요.
LVL도 마찬가지인 것 같고.
예를 들어 구글의 인앱빌링 라이브러리를 쓸텐데 이 라이브러리 자체를 바꿔치기 해버린다면 해킹이 가능할 것 같기도 해요. 퍼블릭 키를 알아낼 필요조차도 없겠죠.
인앱빌링 메커니즘을 자세히 들여다 본적이 없어서 제가 공상을 하는 것일수도 있는데
다른 사람들은 어떻게 하는지 궁금해지네요. 이걸 막지 못하면 전세계의 모든 개발자가 똑같이 당할텐데 구글에서는 뒷짐지고 있는 건가요?
아... 이런 데 꽂혀버리면 안되는데... 지금 할 일이 무지 많은데... T.T
누군가 구세주가 나타나 이렇게 하면 됩니다...라고 해주시면 좋겠는데... 제 능력 밖이네요.
저도 시간 날 때마다 틈틈이 생각해볼께요. 답이 나올랑가 모르겠네요.
근데 한 가지 궁금한 게 다시 패킹한 것 같다고 하셨는데
어느 부분이 바뀐 것인지 알 수 있나요? 그걸 안다면 방법론을 추리해 볼 수도 있을 것 같은데요.
해킹과 보안의 싸움에서 항상 해킹이 앞서기 때문에 딱히 방법이 없어 보이기는 합니다.
제가 들은 경우는 인도에서 있던 일인데요.
광고 무료앱의 광고 SDK을 해킹해서 유료 결재하게 만든 사건도 있었다고 하더라구요.
이 사건으로 한동안 해당 유료결재 취소해주고 하더니만 좀 지나니까 업체측도 나 몰라라 하더랍니다.
인도애들이 뛰어난건지, 인도 회사가 무책임한건지...
퍼블릭키 어차피 못숨깁니다. LVL은 이미 깨진지 오래구요.
그거 신경끄고 작업하시는게 여러모로 수명연장에 도움이 됩니다.
LVL뿐 아니라 SKT ARM, KT DRM 다 깨졌습니다. 라이브러리 업데이트 해봤자 소용없구요.
어차피 자바는 답이 없습니다.
C네이티브 코드도 뻥뻥 뚫리는데 자바로 답이 나오겠습니까.. 이럴땐 IOS가 부럽죠.
뚫려도 귀차니즘을 유발시키는게...
저도 회사에서 이슈가되서 직접 해본적이 있는데 하루만에 뚫리는 이유는 안드로이드가 자바를 쓰기때문입니다.
C단에서 죽어라고 막아봤자 자바단에서 C단으로 들어가는 엔트리포인트를 잡아야하기때문에 막을 수 없습니다.
C단만 사용해서 막으라고하면 뚫려고 하는 인간들 귀차니즘을 유발시킬수 있겠지만 자바단에서는 어차피
LVL 호출단이 알아서 뚫려있기때문에 하루면 끝입니다.
public key 가 뭔가요?
데이터 암호화할때 쓰는 키를 말씀하시는건가요?