توضّح هذه المقالة كيفية تخصيص ميزة "الحماية من التلاعب" في Google Play لتطبيقاتك وألعابك. لاستخدام ميزات التخصيص الموضّحة في هذه الصفحة، يجب تفعيل الحماية التلقائية مع ميزة "الحماية من التلاعب" في Play Console.
لمحة عن ميزة "الحماية من التلاعب" المخصّصة
تتيح لك ميزة "الحماية من التلاعب" المخصّصة تحديد بعض طرق Java وKotlin التي تحتاج إلى مستوى أمان أقوى داخل تطبيقك. وعند تحميل إصدارك على Google Play، يعطي Google Play الأولوية للحماية المحسَّنة لهذه الطرق المحدّدة.
من خلال تحديد طرق الحماية المحسَّنة، يمكنك تحسين دفاع تطبيقك ضد التلاعب. يمكنك أيضًا استخدام ميزة "حماية الطريقة" للحماية من تسريب أسرار العميل من الرمز الثنائي (على سبيل المثال، المفاتيح أو عناوين URL الحسّاسة التي يجب تضمينها في البرنامج العميل).
إعداد ميزة "الحماية من التلاعب" المخصّصة
اتّبِع الخطوات التالية لتنفيذ ميزة "الحماية من التلاعب" المخصّصة في قاعدة رموز تطبيقك.
الخطوة 1: إضافة واجهة "الحماية التلقائية" إلى قاعدة الرموز البرمجية
أولاً، أضِف واجهة الحماية إلى تطبيقك أو لعبتك.
Kotlin:
package com.google.android.play.protections.annotations/**
* يوضّح هذا التعليق أنّ الطريقة مرشّحة للحصول على حماية مُعززة.
*
* <p>ستتم إزالة هذا التعليق التوضيحي تلقائيًا من رمز dex لحِزمتك
* في الوقت الذي يحمي فيه Google Play حِزمتك. يجب استخدامها فقط
* كتعليق توضيحي على مستوى الطريقة. ولا يُسمح بأي استخدام آخر (مثل الوصول إلى الفئة
* عبر الانعكاس البرمجي في وقت التشغيل).
*/
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
public annotation class PlayAutomaticIntegrityProtection() {}
Java:
package com.google.android.play.protections.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* يوضّح هذا التعليق أنّ الطريقة مرشّحة للحصول على حماية مُعززة.
*
* <p>ستتم إزالة هذه التعليقات التوضيحية تلقائيًا من رمز dex لحِزمتك
* في الوقت الذي يحمي فيه Google Play حِزمتك. يجب استخدامها فقط
* كتعليق توضيحي على مستوى الطريقة. ولا يُسمح بأي استخدام آخر (مثل الوصول إلى الفئة
* عبر الانعكاس البرمجي في وقت التشغيل).
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PlayAutomaticIntegrityProtection {}
# احتفِظ بفئة التعليقات التوضيحية وعناصرها.
-keep class com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection* { *; }
# يتعامل ProGuard تلقائيًا مع خصائص التعليقات التوضيحية على أنها اختيارية، وبالتالي قد يقوم بإزالتها
# في خطوة إخفاء مفاتيح فك التشفير. ستضمن هذه القاعدة الاحتفاظ بها.
-keepattributes RuntimeVisibleAnnotations, AnnotationDefault
# احتفِظ بأي طرق تحتوي على هذا التعليق التوضيحي، مع السماح بإخفاء أسمائها.
-keepclassmembers,allowobfuscation class * {
@com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection *;
}
الخطوة 2: إضافة تعليقات توضيحية إلى الطرق لتوفير حماية مخصّصة
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection
@PlayAutomaticIntegrityProtection()
fun myMethod() {
// Method body...
}
Java
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection;
@PlayAutomaticIntegrityProtection()
public void myMethod() {
// Method body...
}الخطوة 3: (اختيارية) حماية الأسرار من جهة العميل
تعمل الحماية باستخدام الطريقة المخصّصة على إخفاء الرمز مباشرةً داخل نص الطريقة التي تحتوي على التعليق التوضيحي. يمكنك استخدام ذلك لحماية مفاتيح واجهة برمجة التطبيقات الحسّاسة.
Kotlin:
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection
@PlayAutomaticIntegrityProtection()
fun callApi() {
api.connect("YOUR_API_KEY")
}
Java:
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection;
@PlayAutomaticIntegrityProtection()
public static void callApi() {
api.connect("YOUR_API_KEY");
}
الخطوة 4: (اختيارية) إدارة الأعباء الإضافية لأداء الحماية
بشكلٍ تلقائي، يؤدي استدعاء طريقة محمية إلى إضافة وقت إضافي يبلغ عدة أجزاء من الثانية. لذلك، يجب عدم استدعائها في سيناريوهات حساسة للأداء أو في سلسلة التعليمات الرئيسية.
إذا كنت بحاجة إلى حماية طريقة تتطلّب تنفيذًا سريعًا، يتوفّر وضع حماية أخفّ. يمكنك استخدام سمة تعليق توضيحي لاختيار الوصول بشكل أسرع (يتم تحميلها عند بدء التشغيل)، على الرغم من أنّ الحماية المقابلة ليست قوية.
Kotlin:
@PlayAutomaticIntegrityProtection(loadAtStartup = true)
fun callApi() {
api.connect("YOUR_API_KEY")
}
Java:
@PlayAutomaticIntegrityProtection(loadAtStartup = true)
public static void callApi() {
api.connect("YOUR_API_KEY");
}
لاستخدام هذه السمة، أضِف سمة الواجهة إلى نص تعريف التعليق التوضيحي الأصلي من الخطوة 1:
// تحديث حول تعريف "التعليقات التوضيحية" على Kotlin
public annotation class PlayAutomaticIntegrityProtection(
/**
* إذا كانت القيمة صحيحة، فسيتم تحميل الطريقة التي تحتوي على التعليق التوضيحي عند بدء التشغيل. إذا كانت القيمة خطأ، فسيتم
* تحميلها عند الطلب.
*
* <p>في حالة التحميل عند الطلب، فإن استدعاء الطريقة سيؤثر سلبًا على
* الأداء. بالنسبة إلى التحميل عند بدء التشغيل، ستبقى الطريقة غير مشفّرة في الذاكرة
* طوال مدة استخدام التطبيق.
*/
val loadAtStartup: Boolean = false
) {}
الخطوة 5: اختبار تطبيقك
أفضل الممارسات لاختيار الطرق
يؤدي اختيار مجموعة مدروسة من الطرق إلى توفير حماية أقوى بشكل عام. إذا كان كل إصدار جديد يتضمّن طريقة محمية حديثًا، سيكون هذا الإصدار من التطبيق أو اللعبة أكثر مقاومة للهجمات.
كقاعدة عامة لتجنُّب التأثير في أداء تطبيقك، اختَر طرقًا باردة بدلاً من الطرق الساخنة. للحصول على أقصى حماية، اختَر الطرق التي:
- تكون ضرورية للتطبيق (سيتعذّر تشغيل التطبيق في حال إزالتها).
- لا يتم تنفيذها في سلسلة التعليمات الرئيسية أو سلسلة واجهة المستخدم.
- يجب تشغيلها أكثر من مرة خلال فترة استخدام التطبيق، ولكن لا يجب تشغيلها في حلقة متكررة.
- أن تكون غير بسيطة (أي تحتوي على رمز برمجي أو بيانات غير بسيطة).
- لا يتم تنفيذها أثناء بدء التشغيل، إذا أمكن ذلك.
- تمت إضافتها حديثًا أو إعادة تصميمها بشكل كبير في الإصدار.
- ألّا تكون طرقًا مجرّدة أو طرق واجهة أو منشئات
- لا تستخدِم الانعكاس ولا تحمّل مكتبة مجمّعة من رموز برمجية أصلية مباشرةً.
إزالة الحماية المخصّصة
إذا لم تعُد تريد حماية طريقة معيّنة، يمكنك ببساطة إزالة التعليق التوضيحي @PlayAutomaticIntegrityProtection().