보안 및 디자인

인앱 결제 구현을 디자인할 때는 이 문서에 설명되어 있는 보안 및 디자인 가이드라인을 충실히 따르시기 바랍니다. 여기서 소개하는 가이드라인은 Google Play의 인앱 결제 서비스를 사용하는 모든 이에게 권장되는 모범 사례입니다.

보안 모범 사례

서버에서 서명 확인 작업 수행

가급적이면 기기가 아니라 원격 서버에서 서명 확인을 수행하세요. 서버에서 확인 프로세스를 구현해야 공격자가 개발자의 .apk 파일을 리버스 엔지니어링하여 확인 프로세스를 뚫고 침입하기 어려워지기 때문입니다. 보안 처리를 원격 서버로 오프로드할 경우 기기와 서버 간 핸드셰이크가 안전한지 확인하세요.

잠금 해제된 콘텐츠 보호

악의적인 사용자가 잠금 해제된 콘텐츠를 다시 배포하지 못하도록, .apk 파일에 콘텐츠를 포함시키지 마세요. 그 대신, 다음 중 하나를 수행하세요.

  • 콘텐츠 피드와 같이, 콘텐츠를 실시간으로 전달하는 서비스를 사용합니다. 실시간 서비스를 통해 콘텐츠를 전달하면 콘텐츠를 최신 상태로 유지할 수 있습니다.
  • 원격 서버를 사용하여 콘텐츠를 전달합니다.

원격 서버나 실시간 서비스에서 콘텐츠를 전달할 때, 잠금 해제된 콘텐츠를 기기 메모리에 저장하거나 기기의 SD 카드에 저장할 수 있습니다. SD 카드에 콘텐츠를 저장할 경우에는 콘텐츠를 암호화하고 기기 고유의 암호화 키를 사용하세요.

코드 난독 처리

공격자가 보안 프로토콜과 기타 애플리케이션 구성 요소를 리버스 엔지니어링하기 어렵게 만들기 위해, 인앱 결제 코드를 난독 처리해야 합니다. 개발한 코드에 대해 Proguard 등과 같은 난독 처리 도구를 실행하는 것이 좋습니다.

난독 처리 프로그램을 실행하는 것 외에도, 다음과 같은 기법을 활용해 인앱 결제 코드를 난독 처리하는 것이 좋습니다.

  • 메서드를 다른 메서드로 인라인 처리합니다.
  • 문자열을 상수로 정의하는 대신 즉석에서 생성합니다.
  • Java 리플렉션(reflection)을 사용하여 메서드를 호출합니다.

이런 기법을 사용하면 애플리케이션의 공격 표면을 줄이고 인앱 결제 구현을 손상시킬 수 있는 공격을 최소화하는 데 도움이 될 수 있습니다.

참고: Proguard를 사용해 코드를 난독 처리할 때는 Proguard 구성 파일에 다음 행을 추가해야 합니다.

-keep class com.android.vending.billing.**

모든 샘플 애플리케이션 코드 수정

인앱 결제 샘플 애플리케이션은 공개 배포되므로 누구든 다운로드할 수 있습니다. 따라서 공개적으로 게시된 샘플 코드를 정확히 그대로 사용하면 공격자가 애플리케이션을 비교적 쉽게 리버스 엔지니어링할 수 있습니다. 샘플 애플리케이션은 예시로만 활용하도록 만든 것입니다. 샘플 애플리케이션 중 일부를 사용할 경우에는 애플리케이션을 게시하거나 프로덕션 애플리케이션의 일부로 출시하기 전에 적절히 수정해야 합니다.

특히, 공격자들은 애플리케이션에서 알려진 진입점과 출구점을 노리므로, 자신이 개발한 코드에 샘플 애플리케이션과 똑같은 부분이 있다면 이런 부분을 수정하는 것이 중요합니다.

보안 랜덤 Nonce 사용

Nonce가 예측 가능하거나 재사용되면 안 됩니다. Nonce를 생성할 때는 항상 암호화되어 안전한 난수 생성기(예: SecureRandom)를 사용하세요. 그러면 재생 공격 감소 효과를 볼 수 있습니다.

또한, 서버에서 Nonce 확인을 수행할 경우에는 서버에서 Nonce를 생성해야 합니다.

구매 요청 시 개발자 페이로드 문자열 설정

In-app Billing Version 3 API를 사용하면 Google Play로 구매 요청을 보낼 때 '개발자 페이로드' 문자열 토큰을 포함할 수 있습니다. 일반적으로, 이 토큰은 특정 구매 요청을 고유하게 식별하는 문자열 토큰을 전달하는 데 사용됩니다. 문자열 값을 지정하면 Google Play가 이 문자열을 구매 응답과 함께 반환합니다. 그 후에 이 구매에 대해 쿼리하면 Google Play는 구매 세부정보와 함께 이 문자열을 반환합니다.

애플리케이션이 구매한 사용자를 쉽게 식별할 수 있게 해주는 문자열 토큰을 전달해야 다음에 이 구매가 특정 사용자의 적법한 구매임을 확인할 수 있습니다. 소비성 아이템인 경우에는 임의로 생성되는 문자열을 사용할 수 있지만, 비소비성 아이템인 경우에는 사용자를 고유하게 식별하는 문자열을 사용해야 합니다.

참고: 사용자의 이메일 주소가 변경될 수 있으므로, 페이로드 문자열에는 이메일 주소를 사용하지 마세요.

Google Play에서의 응답을 돌려보낼 때는 개발자 페이로드 문자열이 이전에 구매 요청과 함께 보낸 토큰과 일치하는지 확인하세요. 더욱 철저한 보안 예방 조치로서, 자체적인 보안 서버에서 확인을 수행해야 합니다.

상표 및 저작권 침해에 대한 조치

자신의 콘텐츠가 Google Play에서 재배포되고 있는 사실을 알게 되는 경우에는 신속하고 단호하게 조치를 취하세요. 상표권 침해 고지 또는 저작권 침해 고지를 정식으로 제출하세요.

잠금 해제된 콘텐츠에 대한 취소 가능성(Revocability) 구성표 구현

원격 서버를 사용하여 콘텐츠를 전달하거나 관리하고 있다면, 사용자가 콘텐츠에 액세스할 때마다 애플리케이션이 잠금 해제된 콘텐츠의 구매 상태를 확인하도록 하세요. 이를 통해 필요할 때 사용을 취소하여 프라이버시 침해를 최소화할 수 있습니다.

Google Play 공개 키 보호

악의적인 사용자와 해커로부터 공개 키를 안전하게 보호하려면 어떤 코드에든 공개 키를 리터럴 문자열로 삽입하지 마세요. 그 대신, 런타임에 문자열 조각으로부터 문자열을 생성하거나 비트 조작(예: 다른 문자열과 함께 XOR 사용)을 통해 실제 키를 숨기세요. 키 자체는 비밀 정보가 아니지만, 해커나 악의적인 사용자가 공개 키를 다른 키로 쉽사리 바꾸도록 방치하지 않기 위한 조치입니다.