2012-05-03 7 views
4

現在、アプリ内購入をコード化しようとしています。私はドキュメント、情報、Googleが処理しないもののベストプラクティスに関するチュートリアルを探していました。私がこれまで行ってきた何Google Androidアプリ内購入「コンテンツ配信」コンテンツを正しく配信するには?

は私がGoogle Playでに話しハンドル課金サービスを実行しています。このサービスは "サンプル"トランザクションを完了することができ、私のアプリケーションはメッセージを受け取ります。

私は今、コンテンツをデバイスに配信したいと思います。私が次に考える必要があると思うこと:

  1. 私のアプリは私のサーバーに連絡し、成功した取引の証明を示す必要があります。いくつかの証明書の手を振るかそのようなナンセンスをしないでください。

  2. 次に、コンテンツをダウンロードし、そのコンテンツをデータベースに配置します。おそらく、ある種のデバイス固有の暗号化を使ってデータベースを暗号化するべきです。

私は上記の2つのことと、実行する必要がある他のことを行う方法を学びたいと考えています。妥当な量のセキュリティ/暗号化が欲しいです。どんなドキュメンテーション/チュートリアル/サンプルプロジェクトも素晴らしいだろう、私はこのようなものを探してみたが、私が探していたものは見つけられなかった。

答えて

3

サンプルの請求サービスクライアントコードにいくつか変更を加える必要があります。

まず、サーバを呼び出してRestoreTransactionsのいずれかに使用されるナンスを取得するか、購入を行ってできるだけ安全なものにする必要があります。

何が起こるかを考えてみましょう。

/** 
* This is called when Android Market sends information about a purchase state 
* change. The signedData parameter is a plaintext JSON string that is 
* signed by the server with the developer's private key. The signature 
* for the signed data is passed in the signature parameter. 
* @param context the context 
* @param signedData the (unencrypted) JSON string 
* @param signature the signature for the signedData 
*/ 
private void purchaseStateChanged(Context context, String signedData, String signature) { 
    Intent intent = new Intent(Consts.ACTION_PURCHASE_STATE_CHANGED); 
    intent.setClass(context, BillingService.class); 
    intent.putExtra(Consts.INAPP_SIGNED_DATA, signedData); 
    intent.putExtra(Consts.INAPP_SIGNATURE, signature); 
    context.startService(intent); 
} 

あなたはBillingService.java内handleCommandを見れば、それはこの意図を処理します:これは、その後thePurchaseStateChanged関数を呼び出し

/** 
* The {@link BillingReceiver} sends messages to this service using intents. 
* Each intent has an action and some extra arguments specific to that action. 
* @param intent the intent containing one of the supported actions 
* @param startId an identifier for the invocation instance of this service 
*/ 
public void handleCommand(Intent intent, int startId) { 
    String action = intent.getAction(); 
    if (Consts.DEBUG) { 
     Log.i(TAG, "handleCommand() action: " + action); 
    } 
    if (Consts.ACTION_CONFIRM_NOTIFICATION.equals(action)) { 
     String[] notifyIds = intent.getStringArrayExtra(Consts.NOTIFICATION_ID); 
     confirmNotifications(startId, notifyIds); 
    } else if (Consts.ACTION_GET_PURCHASE_INFORMATION.equals(action)) { 
     String notifyId = intent.getStringExtra(Consts.NOTIFICATION_ID); 
     getPurchaseInformation(startId, new String[] { notifyId }); 
    } else if (Consts.ACTION_PURCHASE_STATE_CHANGED.equals(action)) { 
     String signedData = intent.getStringExtra(Consts.INAPP_SIGNED_DATA); 
     String signature = intent.getStringExtra(Consts.INAPP_SIGNATURE); 
     purchaseStateChanged(startId, signedData, signature); 
    } else if (Consts.ACTION_RESPONSE_CODE.equals(action)) { 
     long requestId = intent.getLongExtra(Consts.INAPP_REQUEST_ID, -1); 
     int responseCodeIndex = intent.getIntExtra(Consts.INAPP_RESPONSE_CODE, 
       ResponseCode.RESULT_ERROR.ordinal()); 
     ResponseCode responseCode = ResponseCode.valueOf(responseCodeIndex); 
     checkResponseCode(requestId, responseCode); 
    } 
} 

ここでは、Googleのプレイによって呼び出されるBillingReceiverです。この関数は、コンテンツ配信用のセッションを作成するためのサーバーへの呼び出しに置き換える必要があります。クラウド内のトランザクションを検証するには、Security.javaのコードをサーバー側に移植する必要があります。

/** 
* Verifies that the data was signed with the given signature, and calls 
* {@link ResponseHandler#purchaseResponse(Context, PurchaseState, String, String, long)} 
* for each verified purchase. 
* @param startId an identifier for the invocation instance of this service 
* @param signedData the signed JSON string (signed, not encrypted) 
* @param signature the signature for the data, signed with the private key 
*/ 
private void purchaseStateChanged(int startId, String signedData, String signature) { 
    ArrayList<Security.VerifiedPurchase> purchases; 
    purchases = Security.verifyPurchase(signedData, signature); 
    if (purchases == null) { 
     return; 
    } 

    ArrayList<String> notifyList = new ArrayList<String>(); 
    for (VerifiedPurchase vp : purchases) { 
     if (vp.notificationId != null) { 
      notifyList.add(vp.notificationId); 
     } 
     ResponseHandler.purchaseResponse(this, vp.purchaseState, vp.productId, 
       vp.orderId, vp.purchaseTime, vp.developerPayload); 
    } 
    if (!notifyList.isEmpty()) { 
     String[] notifyIds = notifyList.toArray(new String[notifyList.size()]); 
     confirmNotifications(startId, notifyIds); 
    } 
} 

公開されているSecurity.javaファイルのサーバー側に公開鍵を設定してください。

+0

ありがとうございました!その他の質問:BillingSecurity.javaをどこかのサーバーにダンプするだけですか?そして、それに接続して公開鍵を取得し、公開鍵などを比較するにはどうしたらいいですか? – naradlov

+0

以前はAppEngineインスタンスに入れていたので、これは私の経験です。 nonceをDB(サーバー側)に保存し、それを手元のトランザクションに関連付けるには、サーバーへの呼び出しが必要です。私は通常、タイムスタンプと、電話から得られるいくつかのデータ(ANDROID_IDなど)の組み合わせを使用します。そのノンスが課金クライアントに送信されます。 Security.javaモジュールには、開発者のダッシュボードからの公開鍵に基づいて署名を検証するコードが含まれています。 – dagalpin

+0

ありがとう、私はまだいくつかの作業があります。これは多くの助けになります。 – naradlov

関連する問題