أساسيات توقيع التطبيقات: مخازن المفاتيح في أندرويد
أساسيات توقيع التطبيقات: مخازن المفاتيح في أندرويد
قبل توزيع أي تطبيق أندرويد عبر متجر Google Play — أو تثبيته مباشرة على جهاز خارج وضع التصحيح — يجب أن يكون موقعاً رقمياً. يُثبت التوقيع أن ملف APK أو AAB صادر عن طرف موثوق (أنت المطور) ولم يتم العبث به منذ إنشائه. يتناول هذا الدرس كل ما تحتاج معرفته: ما هو مخزن المفاتيح (keystore)، وكيفية إنشائه، وكيفية ضبط الأسماء المستعارة للمفاتيح وكلمات المرور، وكيفية ربط كتلة signingConfigs في Gradle بحيث تُوقَّع بنيات الإصدار تلقائيًا.
ما هو مخزن المفاتيح؟
مخزن المفاتيح (keystore) هو ملف ثنائي (بامتداد .jks أو .keystore عادةً) يعمل حاوية آمنة. يخزن إدخالاً واحدًا أو أكثر من المفاتيح، يتضمن كل منها مفتاحاً خاصًا وسلسلة شهادات المفتاح العام المرتبطة به. يستخدم أندرويد المفتاح الخاص داخل مخزن المفاتيح لتوقيع APK أو AAB، وتستخدم الأجهزة المفتاح العام المقابل للتحقق من التوقيع عند التثبيت.
- كلمة مرور مخزن المفاتيح — تحمي ملف مخزن المفاتيح نفسه.
- الاسم المستعار للمفتاح (key alias) — اسم يمكن قراءته يعرّف إدخال مفتاح محددًا داخل مخزن المفاتيح.
- كلمة مرور المفتاح — تحمي إدخال المفتاح الفردي (يمكن أن تكون مطابقة لكلمة مرور مخزن المفاتيح، لكن إبقاؤهما منفصلتين أكثر أمانًا).
- الصلاحية — توصي Google بصلاحية لا تقل عن 25 عامًا لضمان تغطية المفتاح لكامل دورة حياة التطبيق.
إنشاء مخزن المفاتيح باستخدام keytool
يأتي JDK (مجموعة تطوير Java) مع أداة سطر الأوامر keytool التي تُنشئ مخازن المفاتيح وتديرها. نفّذ الأمر التالي في طرفيتك (استبدل العناصر النائبة بقيمك الخاصة):
إنشاء مخزن مفاتيح جديد
keytool -genkey -v \
-keystore ~/keys/my-release-key.jks \
-storetype JKS \
-keyalg RSA \
-keysize 2048 \
-validity 10000 \
-alias my_key_alias
تعني الأعلام ما يلي:
-keystore— المسار الذي سيُكتب فيه ملف مخزن المفاتيح الجديد.-storetype JKS— استخدام تنسيق Java KeyStore (مقبول أيضًا:PKCS12).-keyalg RSAو-keysize 2048— RSA بطول 2048 بت هو الحد الأدنى المقبول من متجر Play.-validity 10000— صلاحية لمدة تقارب 27 عامًا.-alias— الاسم الذي ستشير إليه في Gradle.
بعد تنفيذ الأمر، سيطلب منك keytool بشكل تفاعلي كلمة مرور مخزن المفاتيح وكلمة مرور المفتاح وحقول الاسم المميز (الاسم الأول والأخير، والمؤسسة، والمدينة، والبلد). أدخل هذه البيانات بدقة — يخزنها متجر Play للتحقق من الهوية.
تخزين بيانات الاعتماد بأمان باستخدام ملف key.properties
كتابة كلمات المرور مباشرةً في build.gradle خطأ أمني جسيم — كل من يستنسخ مستودعك سيحصل على بيانات اعتماد التوقيع. الاتفاقية المتبعة في مجتمع Flutter هي تخزين بيانات الاعتماد في ملف key.properties يقع خارج نطاق التحكم في الإصدار.
android/key.properties
storePassword=yourKeystorePassword
keyPassword=yourKeyPassword
keyAlias=my_key_alias
storeFile=../../keys/my-release-key.jks
أضف key.properties إلى .gitignore فورًا:
.gitignore (قسم أندرويد)
# بيانات اعتماد التوقيع — لا تُودعها في المستودع
key.properties
*.jks
*.keystore
ضبط signingConfigs في build.gradle
افتح android/app/build.gradle. تحتاج إلى (1) تحميل ملف key.properties، و(2) الإعلان عن كتلة signingConfigs، و(3) تطبيق هذا الإعداد على نوع بناء release.
android/app/build.gradle — إعداد التوقيع الكامل
// 1. حمّل key.properties في أعلى الملف، قبل android {}
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
// ... compileSdkVersion و defaultConfig وما إلى ذلك الحالية
// 2. أعلن عن إعداد التوقيع
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] != null
? file(keystoreProperties['storeFile'])
: null
storePassword keystoreProperties['storePassword']
}
}
// 3. طبّقه على نوع بناء release
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
}
storeFile يمنع Gradle من الانهيار على آلات CI حيث قد لا يوجد key.properties. على CI يجب حقن بيانات اعتماد التوقيع عبر متغيرات البيئة أو مديري الأسرار بدلًا من ذلك.بناء APK أو AAB إصدار موقع
بمجرد ضبط Gradle، نفّذ أحد أوامر Flutter CLI التالية من جذر المشروع:
بناء مخرجات إصدار موقعة
# بناء App Bundle موقع (المفضل لمتجر Play)
flutter build appbundle --release
# بناء APK موقع (للتثبيت المباشر أو Amazon Appstore)
flutter build apk --release
# بناء APK ضخم يحتوي على جميع ABIs (أكبر حجمًا، مفيد لـ sideloading)
flutter build apk --release --split-per-abi
سيُكتب AAB الموقع في build/app/outputs/bundle/release/app-release.aab، والـ APK في build/app/outputs/flutter-apk/app-release.apk. يمكنك التحقق من التوقيع بـ:
التحقق من توقيع المخرج
keytool -printcert -jarfile build/app/outputs/flutter-apk/app-release.apk
Play App Signing مقابل التوقيع الذاتي
يقدم Google Play خدمة Play App Signing حيث تدير Google مفتاح التوقيع النهائي وتقوم أنت فقط برفع مفتاح الرفع (upload key). إذا اشتركت:
- مفتاح الرفع (الذي تولّده أعلاه) يوقّع الـ AAB الذي ترفعه.
- تُعيد Google توقيع التطبيق بـ مفتاح توقيع التطبيق قبل توزيعه على الأجهزة.
- إذا تعرّض مفتاح الرفع للاختراق، يمكنك طلب إعادة تعيين المفتاح. أما إذا وقّعت بنفسك وفقدت المفتاح، فتطبيقك لا يمكن إصداره نهائيًا.
keytool لإنشاء مخزن مفاتيح .jks، وخزّن بيانات الاعتماد في ملف key.properties مدرج في gitignore، وأعلن عن كتلة signingConfigs في build.gradle تقرأ من هذا الملف، ونفّذ flutter build appbundle --release لإنتاج AAB موقع جاهز لمتجر Play. احتفظ بنسخة احتياطية من مخزن المفاتيح فورًا.