Frage

Ich habe eine Android -App erstellt, in der Artikel mithilfe von Mitarbeitern gekauft werden können In-App-Billing. Wenn ein Artikel gekauft wird, kann die Transaktion leicht zwischen Android -Markt und dem Telefon synchronisiert werden, um in der App verwendet zu werden. Aber ich brauche meinen Server, um mich des Kaufs zu bewusst. Die Entscheidung, App-spezifische Daten zu liefern, sollte auf meinem Server und nicht in der Client-App getroffen werden.

Z.B

  1. Der Benutzer kauft Artikel X vom Android -Markt.
  2. Transaktionsdaten y werden an den Client gesendet.
  3. Client sendet Y an meinen Server.
  4. Client bittet den Server, Inhalte für X zu liefern.
  5. Server liefert Inhalte Wenn y gültig ist. Wie kann das erreicht werden?

Q: Wie überprüfe ich, dass Transaktionsdaten, die vom Android -Client stammen (vermutlich von Google -Servern stammen), nicht gefälscht sind? Der Hacker hat die Daten nicht generiert.

Google Server -> Android Client -> Mein Server -> Android -Client

Vielleicht ist dies eher eine PHP -Frage als alles andere. Was sollte mein Serverskript (PHP) genau tun, um zu überprüfen, ob die abgerufenen Daten real sind?

War es hilfreich?

Lösung

Verwenden Sie OpenSSL_verify ($ data, $ signature, $ key).

Die Variablen $ Data und $ Signature sollten mithilfe von HTTPS vom Android -Client an Ihren PHP -Server gesendet werden. Die Transaktion enthält beide Elemente. Senden Sie das an Ihre Server, bevor Sie die Transaktion im Client bestätigen. (Siehe Dokumentation hier - http://developer.android.com/guide/market/billing/billing_integrate.html)

Der Variable $ -Kaste ist Ihr Google Public Key, der in Ihrem Publisher-Konto aus dem LICENSING & IN-APP-Abrechnungsgremium verfügbar ist. Kopieren Sie den öffentlichen Schlüssel und verwenden Sie diesen in Ihrem PHP -Code, verwenden Sie vorzugsweise eine Konfigurationsdatei, die Sie auf Ihren Servern installieren, und verwenden Sie in Ihrem tatsächlichen PHP -Code.

Wenn der Anruf openSSL_verify erfolgreich ist, sollten Sie die Bestellnummern auf Ihren Servern speichern und sicherstellen, dass sie eindeutig sind, damit sie nicht wiederholt werden können. Beachten Sie, dass ein einzelner Dateneingang und ein Signaturpaar viele Bestellnummern enthalten könnten, obwohl es normalerweise eine Bestellung ist.

Andere Tipps

Wir verwendeten Androidbillinglibrary.

Installieren Sie dies als Projekt in Eclipse und lassen Sie Ihr Projekt es als Bibliothek importieren.

Wir haben BillingController.Iconfiguration implementiert, so etwas wie

import net.robotmedia.billing.BillingController;

public class PhoneBillingConfiguration implements BillingController.IConfiguration{
    @Override
    public byte[] getObfuscationSalt() {
        return new byte[] {1,-2,3,4,-5,6,-7,theseshouldallberandombyteshere,8,-9,0};
    }

    @Override
    public String getPublicKey() {
        return "superlongstringhereIforgothowwemadethis";
    }
}

Dann haben wir uns für unsere Bewerbung erweitert Application:

public class LocalizedApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

//      BillingController.setDebug(true);
        BillingController.setConfiguration(new PhoneBillingConfiguration());
    }
}

AndroidManifest umfasst dies (und alle anderen Dinge)

<application
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:name=".LocalizedApplication"   <!-- use your specific Application  -->
    android:largeHeap="true"
    android:hardwareAccelerated="true"
    >

    <!-- For billing -->
    <service android:name="net.robotmedia.billing.BillingService" />
        <receiver android:name="net.robotmedia.billing.BillingReceiver">
        <intent-filter>
            <action android:name="com.android.vending.billing.IN_APP_NOTIFY" />
            <action android:name="com.android.vending.billing.RESPONSE_CODE" />
            <action android:name="com.android.vending.billing.PURCHASE_STATE_CHANGED" />
        </intent-filter>
    </receiver>

Wir haben implementiert ISignatureValidator

public class PhoneSignatureValidator implements ISignatureValidator {
    private final String TAG = this.getClass().getSimpleName();
    private PhoneServerLink mServerLink;


    private BillingController.IConfiguration configuration;

    public PhoneSignatureValidator(Context context, BillingController.IConfiguration configuration, String our_product_sku) {
        this.configuration = configuration;
        mServerLink = new PhoneServerLink(context);
        mServerLink.setSku(our_product_sku);
    }


    @Override
    public boolean validate(String signedData, String signature) {
        final String publicKey;
        if (configuration == null || TextUtils.isEmpty(publicKey = configuration.getPublicKey())) {
            Log.w(BillingController.LOG_TAG, "Please set the public key or turn on debug mode");
            return false;
        }
        if (signedData == null) {
            Log.e(BillingController.LOG_TAG, "Data is null");
            return false;
        }
        // mServerLink will talk to your server
        boolean bool = mServerLink.validateSignature(signedData, signature);
        return bool;
    }

}

Es sind die letzten paar Zeilen oben, in denen Sie Ihre Klasse aufrufen können, die tatsächlich mit Ihrem Server sprechen.

Unser PhoneServerlink beginnt so etwas:

public class PhoneServerLink implements GetJSONListener {

    public PhoneServerLink(Context context) {
        mContext = context;
    }

    public boolean validateSignature(String signedData, String signature) {
        return getPurchaseResultFromServer(signedData, signature, false);
    }

    private boolean getPurchaseResultFromServer(String signedData, String signature,  boolean async) {  
            // send request to server using whatever protocols you like 
    }

}

Transaktionsdaten werden mit einem privaten Schlüssel unterzeichnet, der für Ihre App spezifisch ist. Es gibt auch einen Nonce, um Wiederholungen zu verhindern (dh das Senden derselben, gültigen Daten mehrmals). Wenn Sie überprüfen, ob der Nonce eindeutig ist und die Signatur auf Ihrem Server gültig ist, können Sie einigermaßen sicher sein, dass er nicht gefälscht ist. Überprüfen Sie den Teil über IAB von Diese Google IO -Präsentation für eine Diskussion.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top