Three days ago, I was finalizing the automation of a Ren’Py game’s builds and releases to the Play Store with the Ren’Py Setup action when we encountered an issue that some of you might recognize: Google rejected the package with an error that might seem a bit cryptic if you have never used certificates before:
Your Android App Bundle is signed with the wrong key. Ensure that your App Bundle is signed with the correct signing key and try again. Your App Bundle is expected to be signed with the certificate with fingerprint:
SHA1: BD:98:5A:57:BA:59:13:07:4B:F5:CA:A5:C9:77:2E:D4:2F:2F:96:2D
but the certificate used to sign the App Bundle you uploaded has fingerprint:
SHA1: F5:C6:DB:B1:08:C6:81:EB:7F:CE:9C:6D:28:EA:F1:2E:7B:DF:25:5B
We quickly discovered that the Ren’Py installation used to generate the first builds uploaded to Google Play had long since been deleted and that the data required to push to Google Play had disappeared with it. This post will try to explain how it works, what happened, and how to handle this situation for your own games.
The error is due to the way APK/AAB files work and the way Google ensures that you are the one that generated the file. To do so, they check that the file’s signature matches the certificate that you previously provided to Google.
You may ask “What is a certificate?”. It’s a file that contains information about you and your project and is associated with a private key (the key Google complains about above) that is used to generate the signature Google verifies to ensure that you are the one that created a file.
By default, Ren’Py creates the certificate and its key for you when you install the android DLC; it event creates two sets: one for APK, one for AAB. You can find them in your Ren’Py directory under rapt/android.keystore
(used for the APK) and rapt/bundle.keystore
(used for the AAB). If you have deployed an android game and haven’t done so already, those are the files you want to save somewhere for safekeeping.
When re-installing Ren’Py (after updating the version you use or changing computer for example), the keystore files will be re-generated by Ren’Py with different values, which means that the new android releases will not use the same certificate/key pair and the above error will occur.
There are several ways to fix the problem, let’s go over some of them.
If you still have access to the Ren’Py install you used previously, add support for Android to your current Ren’Py version then import rapt/bundle.keystore
and rapt/android.keystore
from your old Ren’Py to the new installation.
If you have issues when building the Android packages, open rapt/project/local.properties
and rapt/project/bundle.properties
and update the values of key.alias
, key.store.password
, and key.alias.password
to match the values in your old Ren’Py install.
If you have deleted your previous Ren’Py install/lost your keys, you will have to register a new one with Google. If you get to this point, I suggest you skip over to the next way to fix, this section is the minimal way to do it, not the best one. The next section will help you use a more up-to-standard setup before sending you back here.
You may only do this once per year, so save your keystore and store properties in a safe place once you’re done.
First, we need to create the file that will be imported in the store. There are two ways to get this file’s content (copy the output of the commands in a file to send to Google):
rapt
Ren’Py directory in a terminal, then run the following command and press Enter
when prompted for a password (the values in the command are the default ones, check project/bundle.properties
if you have customized your Ren’Py setup):keytool -export -rfc -keystore bundle.keystore -alias android
your.game.abb
by the name of the file that was generated):unzip -p your.game.aab 'META-INF/*.RSA' | keytool -printcert -rfc
Once you have created the certificate file, you are ready to update your certificate on the Play Store. Note that you will have to wait 48 hours before you can actually push a file with the new certificate.
Application integrity
(under Publish
-> Configuration
)Application Signature
tabAsk to reinitialize the importation key
The keystores created by Ren’Py by default do not use the latest industry standards. You can generate your own (and quirky) certificate, and it’s only one command!
Note that changing the certificate may only be done once per year, so save your keystore and keystore properties in a safe place once you’re done.
To generate a new certificate, run the following command after making a few changes:
renpystorepassword
with your desired store passwordrenpy
with the certificate alias you want to use in the storeFR
, Seireitei Country
, Ayoland
, The mine
, Games Department
, and com.ayowel.games.demo
with anything you want. This should be information on your localization and metadata about your game that is ‘visible’ to anyone that will download your apk/aab but is not legal or checked information so you may go wild there (just don’t claim to be an actual company)keytool -genkey -keystore bundle.p12 -storepass renpystorepassword -alias renpy -storetype pkcs12 -keysize 4096 -keyalg rsa -validity 10950 -dname "C=FR,ST=Seireitei,L=Ayoland,O=The mine,OU=Games Department,CN=com.ayowel.games.demo"
Once you have generated the bundle.p12
file, replace the file rapt/bundle.keystore
with it, then modify rapt/project/bundle.properties
as follows:
key.alias=
by the alias you provided in the command (renpy
if you used the command as-is)key.alias.password=
ans key.store.password=
by the store password you provided in the command (renpystorepassword
if you used the command as-is)To use your new certificate for APK builds too, modify rapt/project/local.properties
as follows:
key.alias=
by the alias you provided in the command (renpy
if you used the command as-is)key.alias.password=
ans key.store.password=
by the store password you provided in the command (renpystorepassword
if you used the command as-is)key.store=
to use your new bundle.keystore
instead of android.keystore
When you’re done, verify that everything still works, that you can still create android builds, and that your android builds use your new certificate. Once you have verified this, update your Play Store configuration to use your new certificate.
I hope this helped you understand why the Play Store may block your build uploads and hopefully helped fix it if you ended up here after having the issue.
Keep your keystores and properties files safe and make backups to be able to restore them later if needed.
If you want to automate your builds, take a look at the Ren’Py Setup action on GitHub, which makes use of everything this post talks about to allow you to create AAB/APK builds on-the-fly on GitHub.
Waiting for a package to be uploaded to the Play Store before you’re able to check whether the certificate it contains will be accepted is cumbersome. You can easily check the certificate in a package by extracting it and printing its SHA1 with keytool
(a tool installed with Java).
The following line uses the command-line to extract the certificate and print it, applications such as the Git Bash
(part of Git for Windows) should allow you to run the commands if you are on Windows.
unzip -p your.game.aab 'META-INF/*.RSA' | keytool -printcert
The output should look like this, what you want to look at is the line that starts with SHA1
, which should match the SHA1
expected by Google:
Owner: CN=A Ren'Py Creator
Issuer: CN=A Ren'Py Creator
Serial number: 3092c5c5
Valid from: Mon Mar 06 00:33:40 CET 2023 until: Tue Dec 07 00:33:40 CET 2077
Certificate fingerprints:
SHA1: 0A:4E:26:EE:A0:24:15:59:97:43:63:A4:4C:90:0D:C9:01:DB:0F:75
SHA256: EF:56:A8:B2:AC:65:1C:A5:55:ED:B1:35:DE:0A:EB:45:39:15:91:09:61:1D:35:D1:0A:67:2F:E7:C3:36:6D:7D
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: B6 6E FB A1 31 82 DD 6E 4D 19 42 B5 0A 96 F1 08 .n..1..nM.B.....
0010: CC DE E4 17 ....
]
]