[android] Why is it important to set the developer payload with in-app billing?

I’m using version 3 of the in-app billing API. I have a single, managed, non-consumable item. I have not released this feature in my app yet, so I want to decide on the purchase payload contents before there are any purchases.

From “Security Best Practices”:

Set the developer payload string when making purchase requests

인앱 결제 버전 3 API를 사용하면 Google Play에 구매 요청을 보낼 때 ‘개발자 페이로드’문자열 토큰을 포함 할 수 있습니다. 일반적으로이 구매 요청을 고유하게 식별하는 문자열 토큰을 전달하는 데 사용됩니다. 문자열 값을 지정하면 Google Play는 구매 응답과 함께이 문자열을 반환합니다. 이후에이 구매에 대해 쿼리 할 때 Google Play는 구매 세부 정보와 함께이 문자열을 반환합니다.

나중에 해당 사용자의 합법적 인 구매인지 확인할 수 있도록 애플리케이션에서 구매 한 사용자를 식별하는 데 도움이되는 문자열 토큰을 전달해야합니다. 소모성 품목의 경우 무작위로 생성 된 문자열을 사용할 수 있지만, 비 소모성 품목의 경우 사용자를 고유하게 식별하는 문자열을 사용해야합니다.

Google Play에서 응답을 받으면 개발자 페이로드 문자열이 구매 요청과 함께 이전에 보낸 토큰과 일치하는지 확인하세요. 추가 보안 예방 조치로 자신의 보안 서버에서 확인을 수행해야합니다.

바르게 또는 잘못, 내가 결정 하지 구매 검증을 수행하기 위해 서버를 설정하는 “더 보안 예방 조치”를 취할. 그리고 저는 구매 기록을 저장하지 않습니다. 저는 항상 청구 API를 호출합니다. 이 페이로드 확인을 수행해야하는 이유가 정말로 있습니까? 확인 API 자체는 항목을 구매 한 것으로보고하기 전에 사용자의 신원을 확실히 확인합니다. 공격자가 기기 (앱 또는 Google Play API)를 해킹 한 경우 추가 확인을 수행해도 이점이 없습니다. 쉽게 우회 할 수있는 장치의 사용자 ID 아니면 내가 생각하지 않는 이것을 할 이유가 있습니까?



답변

기록을 보관하지 않으면받은 내용이 보낸 내용인지 확인할 방법이 없습니다. 따라서 개발자 페이로드에 무언가를 추가하는 경우 합법적이라고 믿거 나 (서명이 확인하는 경우 합리적인 가정) 완전히 신뢰하지 않고 참조로만 사용할 수 있지만 라이선스 상태 확인에는 사용할 수 없습니다. 예를 들어 사용자 이메일을 저장하는 경우 다시 입력하도록 요청하는 대신 값을 사용할 수 있습니다. 이는 사용자에게 약간 더 친숙하지만 앱이 없으면 중단되지 않습니다.

개인적으로 저는이 모든 ‘모범 사례’부분이 혼란스럽고 API가 실제로 수행해야하는 작업을 수행하도록하려고합니다. 구매는 Google 계정에 연결되어 있고 Play 스토어는 분명히이 정보를 저장하므로 구매 세부 정보에서이 정보를 제공해야합니다. 적절한 사용자 ID를 얻으려면 IAB API의 결함을 해결하기 위해 추가 할 필요가없는 추가 권한이 필요합니다.

간단히 말해, 자체 서버와 특별한 추가 기능 로직이 없다면 개발자 페이로드를 사용하지 마십시오. IAB v3 API가 작동하는 한 괜찮습니다 (불행히도이 시점에서 상당히 큰 ‘if’임).


답변

애플리케이션에서 구매 한 사용자를 식별하는 데 도움이되는 문자열 토큰을 전달해야합니다.

애플리케이션에서 휴대 전화가 연결된 Google 계정과 다른 고유 한 사용자 로그인 및 ID를 제공하는 경우 개발자 페이로드를 사용하여 구매를 한 계정 중 하나에 구매를 첨부해야합니다. 그렇지 않으면 누군가가 앱에서 계정을 전환하여 구매 한 항목의 혜택을받을 수 있습니다.

예 :

앱에 userA 및 userB에 대한 로그인이 있다고 가정합니다. 그리고 휴대 전화의 Android Google 계정은 X입니다.

  1. userA는 앱에 로그인하여 평생 회원권을 구매합니다. 구매 세부 정보는 Google 계정 X에 저장됩니다.
  2. userA는 로그 아웃하고 userB는 앱에 로그인합니다. 이제 userB는 Android Google 계정이 여전히 X이므로 평생 회원 자격의 혜택을받습니다.

이러한 오용을 방지하기 위해 구매를 계정에 연결합니다. 위의 예에서는 userA가 구매할 때 개발자 페이로드를 “userA”로 설정합니다. 따라서 userB가 로그인하면 페이로드가 로그인 한 사용자 (userB)와 일치하지 않으며 구매를 무시합니다. 따라서 userB는 userA가 구매 한 혜택을받을 수 없습니다.


답변

개발자 페이로드 처리에 대한 또 다른 접근 방식이 있습니다. Nikolay Elenkov가 말했듯이 사용자 ID를 요구하고 앱에 대한 사용자 프로필에 대한 추가 권한을 설정하는 것은 너무 많은 오버 헤드이므로 이것은 좋은 접근 방식이 아닙니다. In-App Billing v3 샘플에서 최신 버전의 TrivialDrive 샘플 앱에서 Google이 말하는 내용을 살펴 보겠습니다.

  • 경고 : 구매를 시작하고 여기에서 확인할 때 임의의 문자열을 로컬에서 생성하는 것이 좋은 방법처럼 보일 수 있지만 사용자가 한 기기에서 항목을 구매 한 다음 다른 기기에서 앱을 사용하는 경우에는 실패합니다. 다른 장치는 원래 생성 한 임의의 문자열에 액세스 할 수 없습니다.

따라서 임의의 문자열은 다른 장치에서 구매 한 항목을 확인하려는 경우 좋은 생각이 아니지만 여전히 구매 응답을 확인하는 데 좋지 않다고 말하지 않습니다. 나는 말하고 싶다-임의의 고유 문자열을 전송하여 구매를 확인하는 데에만 개발자 페이로드를 사용하고 환경 설정 / 데이터베이스에 저장하고 구매 응답에서이 개발자 페이로드를 확인하십시오. 활동 시작시 인벤토리 (인앱 구매)를 쿼리하는 경우-임의의 고유 문자열이 저장되지 않은 다른 기기에서 발생할 수 있으므로 개발자 페이로드를 확인하지 마세요. 그것이 내가 보는 방법입니다.


답변

확인 방법에 따라 developerPayload . 두 가지 시나리오가 있습니다 : 원격 확인 (서버 사용)과 로컬 (장치에서).

섬기는 사람

developerPayload확인 을 위해 서버를 사용하는 경우 장치와 서버 모두에서 쉽게 계산할 수있는 임의의 문자열이 될 수 있습니다. 요청을 수행 한 사용자를 식별 할 수 있어야합니다. 모든 사용자 가정하면 해당 갖는다 accountIddeveloperPayload조합과 같이 계산 될 수있다 purchaseId이와 같은 (SKU 명) :

MD5(purchaseId + accountId)

장치

developerPayload 사용자 이메일이 아니어야합니다 . 이메일을 페이로드로 사용하지 않아야하는 좋은 예는 Google for Work 서비스입니다. 사용자는 계정과 연결된 이메일을 변경할 수 있습니다. 유일한 변함없는 것은accountId . 대부분의 경우 이메일은 괜찮지 만 (예 : Gmail 주소는 현재 변경할 수 없음) 미래를 위해 설계해야합니다.

여러 사용자가 동일한 장치를 사용할 수 있으므로 항목 소유자를 구별 할 수 있어야합니다. 장치 확인의 developerPayload경우 사용자를 고유하게 식별하는 문자열입니다. 예 :

MD5(purchaseId + accountId)

결론

일반적으로 developerPayload두 경우 모두 accountId. 나를 위해 그것은 모호함을 통한 보안 . MD5 (또는 다른 해싱 알고리즘) purchaseId는 계정의 ID를 사용하고 있음을 명시 적으로 표시하지 않고 페이로드를 더 무작위로 만드는 방법입니다. 공격자는 앱이 어떻게 계산되는지 확인하기 위해 앱을 디 컴파일해야합니다. 앱이 더 잘 난독 화되어 있다면.

페이로드는 보안을 제공하지 않습니다. . ‘장치’접근 방식으로 쉽게 스푸핑 될 수 있으며 ‘서버’검사에 아무런 노력을 기울이지 않아도됩니다. Google 게시자 계정 콘솔에서 제공되는 공개 키를 사용하여 서명 확인을 구현해야합니다.

* 이메일 대신 계정 ID 사용에 대한 필독 블로그 게시물입니다.


답변

간단한 드라이브 샘플 작성자가 직접 제공 한 IAB v3에 대한 Google IO 비디오에서이 내용은 비디오 끝 부분에 간략하게 설명되어 있습니다. 예를 들어 공격자가 트래픽을 스니핑하고 성공적인 구매가 포함 된 패킷을 훔친 다음 자신의 장치에서 패킷을 재생하려고 시도하는 등 재생 공격을 방지하기위한 것입니다. 앱이 프리미엄 콘텐츠 (이상적으로는 서버에서)를 릴리스하기 전에 개발자 페이로드 (이상적으로는 서버에서)를 통해 구매자의 신원을 확인하지 않으면 공격자가 성공합니다. 패킷이 손상되지 않았기 때문에 서명 확인에서이를 감지 할 수 없습니다.

제 생각에는이 보호 기능은 클래시 오브 클랜 (어쨌든 사용자를 식별해야하기 때문에 페이로드가 자연스럽게 발생 함)과 같은 온라인 계정 연결이있는 앱, 특히 해킹이 단순한 현지화 된 불법 복제 사례 이외의 광범위한 효과로 멀티 플레이어 게임 플레이를 손상시키는 앱에 이상적이라고 생각합니다. . 반대로 클라이언트 측 해킹이 이미 프리미엄 콘텐츠를 잠금 해제 할 수 있다면이 보호 기능은 그다지 유용하지 않습니다.

(공격자가 페이로드를 스푸핑하려고하면 서명 확인이 실패합니다.)


답변

2018 년 후반 업데이트 : 공식 Google Play 결제 라이브러리는 의도적으로 developerPayload. 에서 여기 :

developerPayload 필드는 이전 구현과의 호환성을 유지하기 위해 유지되는 레거시 필드이지만 인앱 결제 제품 구매 페이지 ( https://developer.android.com/training/in-app-billing/purchase-iab -products.html ),이 필드는 인앱 결제와 관련된 작업을 완료 할 때 항상 사용할 수있는 것은 아닙니다. 그리고 라이브러리는 가장 업데이트 된 개발 모델을 나타내도록 설계 되었기 때문에 구현에서 developerPayload를 지원하지 않기로 결정했으며이 필드를 라이브러리에 포함 할 계획이 없습니다.

developerPayload에서 인앱 결제 로직의 중요한 구현에 의존하는 경우이 필드가 언젠가 (또는 곧) 지원 중단되므로이 접근 방식을 변경하는 것이 좋습니다. 권장되는 접근 방식은 자체 백엔드를 사용하여 주문에 대한 중요한 세부 정보를 확인하고 추적하는 것입니다. 자세한 내용은 보안 및 디자인 페이지 ( https://developer.android.com/google/play/billing/billing_best_practices.html )를 확인 하세요 .


답변

나는 이것으로 고생했다. Google Play 계정은 ‘관리되는’항목 중 하나만 소유 할 수 있지만 여러 기기를 보유 할 수 있기 때문에 (3 개 보유) ‘기기 당’을 판매하는 사람의 위 댓글은 작동하지 않습니다. 첫 번째 장치에 넣을 수 있고 다른 장치에는 넣을 수 없습니다. 프리미엄 업그레이드를 구입하면 모든 휴대폰 / 태블릿에서 작동합니다.

나는 사용자의 이메일 주소를 얻는다는 개념을 경멸하지만 다른 신뢰할 수있는 방법을 실제로 찾지 못했습니다. 따라서 계정 목록에서 “google.com”과 일치하는 첫 번째 계정 (예, 매니페스트에 추가 할 수있는 권한)을 가져온 다음 즉시 해시하여 더 이상 이메일 주소로 사용할 수 없지만 “충분히 고유 한 “토큰. 이것이 개발자 페이로드로 보내는 것입니다. 대부분의 사람들이 Google Play ID로 기기를 활성화하기 때문에 세 기기 모두 동일한 토큰을 받게됩니다 (각 기기에서 동일한 해시 알고리즘 사용).

여러 “사용자”가있는 KitKat에서도 작동합니다. (내 개발자 ID는 한 사용자, 내 테스트 ID는 다른 사용자, 각 사용자는 자신의 샌드 박스에 있습니다).

총 3 명의 사용자가있는 6 개의 장치에서 테스트했으며 각 사용자 장치는 동일한 해시를 반환했으며 다른 사용자는 모두 고유 한 해시를 사용하여 지침을 충족했습니다.

사용자의 이메일 주소를 저장하지 않고 코드에서 바로 전달되어 계정 이름을 해시 함수로 가져오고 해시 만 힙에 저장됩니다.

사용자의 개인 정보를 더욱 존중하는 더 나은 솔루션이있을 수 있지만 지금까지는 찾지 못했습니다. 앱이 게시되면 개인 정보 보호 정책에 사용자 이메일 주소를 사용하는 방법에 대한 매우 명확한 설명을 넣을 것입니다.