Largely based on this work of Marco Aceti.
The main difference is the way the keystore is obtained, making the application debuggable instead of using adb backup (that has been "fixed").
Search on the Internet mate or ask GPT.
Because the PosteId app is frustrating; I want to manage all my OTP credentials with the same app.
You should have installed adb, apktool, apksigner, zipalign, python3 and rg.
I noticed that the newest versions of apktool throw errors when rebuilding; the version that worked for me was 2.11.0.
python3 -m venv .env && \
source .env/bin/activate && \
python -m pip install pyjks asn1;All Android apps are now distributed as an App Bundle, i.e., a collection of APK files each serving a specific purpose. We need to download every APK and patch them all.
for apk in $(adb shell pm path posteitaliane.posteapp.appposteid | awk -F':' '{print $2}'); do
adb pull "$apk"
donefor apk in *.apk; do
apktool d -f $apk
doneNormally we would have to uninstall the original app before installing the patched one, because Android treats the same applicationId as the same package and refuses two differently signed copies.
So, let’s rename the applicationId throughout the decompiled sources.
# Find and replace every occurrence of the string 'posteitaliane.posteapp.appposteid' in all non‑markdown files
rg -l 'posteitaliane\.posteapp\.appposteid' -g !'*.md' \
| xargs sed -i 's/posteitaliane\.posteapp\.appposteid/posteitaliane.posteapp.apppatchedid/g'
# Same thing, but with a slightly different string
rg -l 'posteitaliane/posteapp/appposteid' -g !'*.md' \
| xargs sed -i 's/posteitaliane\/posteapp\/appposteid/posteitaliane\/posteapp\/apppatchedid/g'
# Rename all directories that contain the structure posteitaliane/posteapp/appposteid
fd appposteid -x mv {} {//}/apppatchedid
# Finally, adjust the <permission> tag in AndroidManifest.xml because two apps with different signatures cannot declare the same permission.
rg -l 'it.posteitaliane.provider.READ_DATA_PERMISSION' -g !'*.md' \
| xargs sed -i 's/it.posteitaliane.provider.READ_DATA_PERMISSION/it.patcheditaliane.provider.READ_DATA_PERMISSION/g'for apk in *.apk; do
apktool b -f -d -o "unsigned/$apk" "${apk%.*}"
donePlease note that we added the -d flag that sets android:debuggable to "true" in the APK's compiled manifest.
Google requires every installable APK to be cryptographically signed.
# allineare tutti gli apks
if [[ ! -d "aligned" ]]; then
mkdir "aligned"
fi
for unsigned in unsigned/*.apk; do
zipalign -p -f 4 "$unsigned" "aligned/${unsigned##*/}"
doneCreate a keystore (named patch.keystore here):
keytool -genkeypair -v -keystore patch.keystore -keyalg RSA -keysize 2048 -validity 3650 -alias patch -storepass patchedAccept the default prompts and type y when asked for confirmation.
if [[ ! -d "signed" ]]; then
mkdir "signed"
fi
#firmare tutti gli apks
for aligned in aligned/*.apk; do
apksigner sign --ks patch.keystore \
--ks-pass=pass:patched \
--out "signed/${aligned##*/}" \
$aligned
donerm -r base split_config.arm64_v8a split_config.it split_config.en split_config.xxhdpi unsigned alignedNow you can install signed apks like this:
adb install-multiple signed/*.apkLogin with your account in the app. Once you have done that, close it and DO NOT open it again until you have added
the seed into the authenticator.
(Small note: you can actually open the app, but you must avoid tapping “Generate temporary PIN” because that action changes the seed.)
Previously the way to extract SCA_HOLDER.ubr was to do a backup of the
application and
Tu do so, we can use the following command: ```bash adb shell run-as
posteitaliane.posteapp.apppatchedid cat
/data/data/posteitaliane.posteapp.apppatchedid/files/SCA_HOLDER.ubr >
SCA_HOLDER.ubr ```
Now you will have the beautiful file that you were searching for in the current
directory.
The following Python script reads the UberKeyStore file, extracts the secret, and prints the Base32‑encoded seed.
import jks
import asn1
import base64
ks = jks.bks.UberKeyStore.load('SCA_HOLDER.ubr', 'SCA_HOLDER')
c = ks.entries['_APP_SECRET'].cert
decoder = asn1.Decoder()
decoder.start(c)
decoded = decoder.read()
ski = decoded[1][0][-1][0][0][1]
seed = base64.b32encode(ski).rstrip(b"=").decode('utf-8')
print(seed)Add this seed to your favourite authenticator with these settings:
| Setting | Value |
|---|---|
| Hash function | SHA1 |
| Period | 120 |
| Digits | 6 |
Now compare the TOTP generated by your authenticator with the one shown in the PosteId app—if they match, you’ve have done it!
You can now delete everything in this folder, including the intermediate build artefacts, and the PosteId app.
Hope that's helpfull for someone else other than me!
I have done correctly all the steps for modifying the original app, but when I want to start it on the device I get an error: "Si è verificato un errore in fase di avvio dell'App. Ti consigliamo di riprovare e di controllare l'eventuale disponibilità sullo store di aggiornamenti dell'app"