Android installs only signed APKs. Debug builds use a throwaway key in ~/.android/debug.keystore; a release needs your own key in a keystore. With Play App Signing (App Bundles and Signing) it is the upload key, proving to Google that a bundle comes from you. Create it with the JDK's keytool, outside the project, with the password in an environment variable rather than in a file:
mkdir -p ../keys
keytool -genkeypair -keystore ../keys/booknest-upload.jks -alias booknest \
-keyalg RSA -keysize 2048 -validity 10000 \
-dname "CN=BookNest Team, O=Example Books, L=Kota Kinabalu, C=MY" \
-storepass "$BOOKNEST_STORE_PASS"
keytool -list -keystore ../keys/booknest-upload.jks -storepass "$BOOKNEST_STORE_PASS"Output
Generating 2,048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 10,000 days for: CN=BookNest Team, O=Example Books, L=Kota Kinabalu, C=MY ... booknest, Sep 25, 2026, PrivateKeyEntry, Certificate fingerprint (SHA-256): AA:F4:72:D5:8E:4E:5D:A3:50:ED:B3:BE:06:E6:AD:93:2A:63:DE:8C: 71:8A:C0:69:61:40:33:33:A7:DB:72:C9
The key is valid for about 27 years; Google Play 1 requires validity past 22 October 2033. Without -dname, keytool asks for each name part. PKCS12 keystores use one password for store and key. A build.json next to config.xml tells Cordova 129 where the key is, and holds no secret:
{
"android": {
"release": {
"keystore": "../keys/booknest-upload.jks",
"alias": "booknest"
}
}
}