חתימת אפליקציות אנדרואיד: Keystore, Gradle, CI/CD ו-Play App Signing
אובדן קובץ ה-keystore הוא בלתי הפיך. אם המפתח הפרטי אבד, עדכון האפליקציה הקיימת שלך ב-Google Play הופך לבלתי אפשרי. תצטרך לפרסם אפליקציה חדשה עם שם חבילה חדש, ולאבד את כל הביקורות, היסטוריית ההורדות ודירוגי החיפוש. מניסיוננו, אירועים כאלה עולים למפתחים חודשים של השבתה והפסד הכנסות. כדי למנוע זאת, אנו מגדירים חתימת אפליקציות אנדרואיד מקצה לקצה: מהפקת keystore ועד CI/CD ו-Play App Signing. המהנדסים שלנו מוסמכים על ידי Google עם שנים של ניסיון בפיתוח אנדרואיד. צור קשר להערכת פרויקט חינמית ופתרון אופטימלי.
במדריך זה נסקור יצירת keystore, הגדרת Signing Config ב-Gradle ללא אחסון סיסמאות בקוד, הפעלת Play App Signing ואוטומציה של חתימה ב-CI. ביצוע שלבים אלה יגן על המפתחות שלך וימנע אובדן גישה לאפליקציה שלך.
יצירה ואחסון של ה-Keystore
צור באמצעות keytool:
keytool -genkeypair -v \
-keystore release.keystore \
-alias myapp \
-keyalg RSA \
-keysize 2048 \
-validity 10000 \
-storetype JKSkeytool -genkeypair -v \ -keystore release.keystore \ -alias myapp \ -keyalg RSA \ -keysize 2048 \ -validity 10000 \ -storetype JKS הוא כ-27 שנים. Google ממליצה על לפחות 25 שנים עבור אפליקציות ב-Play Store. תקופה קצרה יותר עלולה לגרום ל-Google Play לדחות עדכונים עתידיים. אנו ממליצים להשתמש בפורמט PKCS12 (-validity 10000) — מאובטח יותר ותואם יותר.
אין לאחסן את ה-keystore במאגר Git, אפילו לא פרטי. כללי אחסון: גיבוי מוצפן לפחות בשני אחסוני ענן, עותק פיזי מחוץ לאתר, וסיסמאות בנפרד מהקובץ.
פרמטרי Keystore: המלצות
| פרמטר | המלצה | למה |
|---|---|---|
| אלגוריתם | RSA 2048 סיביות | איזון בין אבטחה וביצועים |
| תוקף | 10,000 ימים (27 שנים) | מכסה את כל מחזור חיי האפליקציה |
| פורמט | PKCS12 | הצפנה חזקה יותר מ-JKS |
| Alias | שם האפליקציה | נוח למפתחות מרובים |
כיצד להגדיר Signing Config ב-Gradle ללא סיסמאות
קידוד נתיבים וסיסמאות ב--storetype PKCS12 הוא אנטי-תבנית:
// ТАК НЕ ДЕЛАТЬ — пароли в репозитории
signingConfigs {
release {
storeFile file("../keys/release.keystore")
storePassword "mysecretpassword" // в git попадёт
keyAlias "myapp"
keyPassword "mysecretpassword"
}
}הגישה הנכונה היא באמצעות משתני סביבה או build.gradle:
// build.gradle (app)
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('keystore.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias'] ?: System.getenv('KEY_ALIAS')
keyPassword keystoreProperties['keyPassword'] ?: System.getenv('KEY_PASSWORD')
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword'] ?: System.getenv('STORE_PASSWORD')
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}// ТАК НЕ ДЕЛАТЬ — пароли в репозитории signingConfigs { release { storeFile file("../keys/release.keystore") storePassword "mysecretpassword" // в git попадёт keyAlias "myapp" keyPassword "mysecretpassword" } } צריך להיות ב-local.properties. ב-CI, העבר משתני סביבה ישירות. עבור Kotlin DSL, התצורה דומה באמצעות // build.gradle (app) def keystoreProperties = new Properties() def keystorePropertiesFile = rootProject.file('keystore.properties') if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) } android { signingConfigs { release { keyAlias keystoreProperties['keyAlias'] ?: System.getenv('KEY_ALIAS') keyPassword keystoreProperties['keyPassword'] ?: System.getenv('KEY_PASSWORD') storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null storePassword keystoreProperties['storePassword'] ?: System.getenv('STORE_PASSWORD') } } buildTypes { release { signingConfig signingConfigs.release minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } . למידע נוסף על Signing Config.
נוסף: אימות טביעת אצבע
keytool -list -v -keystore release.keystore -alias myapp ב-Play Console: Setup → App signing → App signing key certificate — השווה SHA-256. עבור טביעות אצבע של Firebase/OAuth, השתמש במפתח חתימת האפליקציה, לא במפתח ההעלאה.
כיצד להגן על מפתחות מפני דליפה?
השתמש במשתני סביבה או keystore.properties ב-.gitignore. לעולם אל תאחסן סיסמאות בקוד. עבור CI, השתמש בקידוד base64 של ה-keystore ובסודות מאגר. זה מפחית את הסיכון לחשיפת מפתח אם המאגר נפרץ.
למה להשתמש ב-Play App Signing?
Play App Signing הוא ביטוח: אם מפתח ההעלאה אבד, Google יכולה לסובב אותו. אתה חותם רק על מפתח ההעלאה, ו-Google אורזת מחדש את האפליקציה עם מפתח חתימת אפליקציה נפרד. זה מאה פעמים מאובטח יותר מאחסון מפתח יחיד. הפעל אותו ב-Play Console: Release → Setup → App signing. לאחר ההפעלה, לא ניתן לבטל אותה.
השוואת שיטות חתימה
| שיטה | אבטחה | שחזור | מורכבות |
|---|---|---|---|
| מפתח יחיד (העלאה בלבד) | בינוני | לא | נמוכה |
| Play App Signing | גבוה | כן (דרך Google) | בינונית |
| מפתחות מרובים (ללא Play) | גבוה | לא | גבוהה |
כיצד לשלב חתימה ב-CI/CD?
ב-GitHub Actions:
---
- name: Sign APK
env:
KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
run: |
echo "$KEYSTORE_BASE64" | base64 --decode > release.keystore
./gradlew bundleRelease \
-Pandroid.injected.signing.store.file=$(pwd)/release.keystore \
-Pandroid.injected.signing.store.password=$STORE_PASSWORD \
-Pandroid.injected.signing.key.alias=$KEY_ALIAS \
-Pandroid.injected.signing.key.password=$KEY_PASSWORD
קודד את ה-keystore ב-base64 (getProperty) ושמור אותו בסודות המאגר. על הסוכן, פענח, השתמש ומחק לאחר העבודה.
מה כלול
- יצירת keystore עם פרמטרים מותאמים לפרויקט שלך (אלגוריתם, תוקף, פורמט).
- תצורת Gradle עבור כל בניות ה-flavor.
- אינטגרציה עם Play App Signing (כולל העברת מפתחות).
- הגדרת CI/CD (GitHub Actions, GitLab CI או אחר).
- תיעוד על אחסון וסיבוב מפתחות.
טעויות נפוצות בתצורת חתימה
- אחסון keystore במאגר — המפתח עלול להיפגע.
- שימוש ב-JKS במקום PKCS12 — הצפנה פחות מאובטחת.
- טביעת אצבע שגויה — שירותי Firebase, OAuth מפסיקים לפעול.
- אין גיבוי keystore — אובדן גישה לאפליקציה.
הערכות זמן
הגדרת חתימה עבור flavor אחד אורכת 2 עד 4 שעות. עבור תצורות flavor מרובות ואינטגרציה עם Play App Signing, בערך יום עבודה אחד. קבע ייעוץ לפרויקט שלך היום.
לפי המלצות Android Developers, Play App Signing מפחיתה את הסיכון לאובדן גישה לאפליקציה בסדר גודל.







