This release is a pre-release and may not be stable for production use.
py-tibade: Python Titanium Backup Decrypt
Author: Tet Woo Lee
This is a Python/pycryptodome-based implementation of TitaniumBackupDecrypt, which was originally authored by Brian T. Hafer. It will decrypt backups made by Titanium Backup for Android.
An alternative Python implementation is is TiBUdecrypter created by David O'Rourke.
Installation
This is available on both PyPi:
pip install pytibade
pytibade --version
and conda:
conda create -n pytibade -c twlee79 pytibade
cona activate pytibade
pytibade --version
Usage
positional arguments:
inputfiles Input file(s), either a list of filenames or as an
unexpanded glob wildcards that is expanded internally
optional arguments:
-h, --help show this help message and exit
--version show program's version number and exit
-s SUFFIX, --suffix SUFFIX
Suffix to add to base filename of decrypted files,
appended to stem before any extensions (default:
-decrypted)
-m MATCH_BASENAME, --match_basename MATCH_BASENAME
Regular expression to match base filename of a file,
applied to filename without directory; first capturing
group should be base filename; an error is produced if
files don't match this pattern, which can be ignored
with the `-c` option (default:
(^.*-[0-9\-]+)[.]([a-z]{3})([.a-z]{0,4}))
-p PASSPHRASE, --passphrase PASSPHRASE
Passphrase used to encrypt the backup files, if not
present then user will be prompted to enter one; same
passphrase used for all files. (default: None)
-c, --continue Continue processing next file even if error
encountered; by default script will stop on first
error (default: False)
-v, --verbose Increase logging verbosity, available levels 1 to 3
with `-v` to `-vvv` (default: 0)
Simplest usage: pytibade com.my.favourite.app-20200426-111127.tar.gz
The script will then prompt for the passphrase.
The script can be used to decrypt a batch of files by specifying multiple
inputfiles or wildcards in inputfiles. The same passphrase is used
for all files. The --continue option is useful to persistently attempt to
decrypt all specified files despite earlier failures (useful, for example, if
there is a mixture of encrypted and unencrypted files).
Titanium Backup File Format
Information Source
This information was originally taken from a post on Christian Egger's G+ page that has now disappeared. It has been reformatted a little for markdown by David O'Rourke.
File Format
"TB_ARMOR_V1" '\n'
pass_hmac_key '\n'
pass_hmac_result '\n'
public_key '\n'
enc_privkey_spec '\n'
enc_sesskey_spec '\n'
data
Explanation of format
Each of the 5 "variables" (pass_hmac_key, pass_hmac_result,
public_key, enc_privkey_spec, enc_sesskey_spec) is stored in
Base64 format without linewraps (of course) and can be decoded with:
Base64.decode(pass_hmac_key, Base64.NO_WRAP)
Then the user-supplied passphrase (String) can be verified as follows:
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(new SecretKeySpec(pass_hmac_key, "HmacSHA1"));
byte[] sigBytes = mac.doFinal(passphrase.getBytes("UTF-8"));
boolean passphraseMatches = Arrays.equals(sigBytes, pass_hmac_result);
Then the passphrase is independently hashed with SHA-1. We append [twelve] 0x00
bytes to the 160-bit result to constitute the 256-bit AES key which is used to
decrypt enc_privkey_spec (with an IV of [sixteen] 0x00 bytes). [Decrypt
using AES-256 in CBC mode and perform PKCS7 unpadding with block size 16.]
Then we build the KeyPair object as follows:
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey2 = keyFactory.generatePrivate(
new PKCS8EncodedKeySpec(privateKey)
);
PublicKey public_key2 = keyFactory.generatePublic(
new X509EncodedKeySpec(public_key)
);
KeyPair keyPair = new KeyPair(public_key2, privateKey2);
Then we decrypt the session key as follows:
Cipher rsaDecrypt = Cipher.getInstance("RSA/NONE/PKCS1Padding");
rsaDecrypt.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
CipherOutputStream cos = new CipherOutputStream(baos, rsaDecrypt);
cos.write(enc_sesskey_spec); cos.close();
byte[] sessionKey = baos.toByteArray();
And finally, we decrypt the data itself with the session key (which can be
either a 128-bit, 192-bit or 256-bit key) and with a 0x00 IV. [Remember
to PKCS7 unpad with block size 16].
While the "zero" IV is suboptimal from a security standpoint, it allows files to be encoded faster - because every little bit counts, especially when we store backups with LZO compression.
| Author | Tet Woo Lee |
|---|---|
| Created | 2020-04-26 |
| Copyright | © 2020 Tet Woo Lee |
| License | GPLv3 |
| Dependencies | pycryptodome, tested with v3.8.2 |
Change log
- version 1.0.dev1 2020-04-26
Working version
Metadata
Release files for pytibade 1.0.0.dev1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pytibade-1.0.0.dev1.tar.gz | 8.9 kB | Without provenance | Details for pytibade-1.0.0.dev1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pytibade-1.0.0.dev1-py3-none-any.whl | Python 3 | none | any | Details for pytibade-1.0.0.dev1-py3-none-any.whl |
Total release size: 21.3 kB
Release files / pytibade-1.0.0.dev1.tar.gz
| Download URL | pytibade-1.0.0.dev1.tar.gz |
|---|---|
| Size | 8.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f548a0561889628401f88a05ef98fa151a2449688541717ce3ee53732c4d16cb
|
|
BLAKE2b-256 checksum How to use checksums |
af97237d286db3803f8e58c97f59242c754526adb2b4a3f2d1df7a5cb88dac02
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.1.3.post20200325 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.8.2
|
Release files / pytibade-1.0.0.dev1-py3-none-any.whl
| Download URL | pytibade-1.0.0.dev1-py3-none-any.whl |
|---|---|
| Size | 12.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c74a894aedd954d73f5d6b19ac9d2999014a203400b680a2df52fc9de782f355
|
|
BLAKE2b-256 checksum How to use checksums |
d573d6b22d5f083587842f0f799019427090024e930b27aecf7f03a5af68e3da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.1.3.post20200325 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.8.2
|
Security for pytibade 1.0.0.dev1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.