Get files from password protected snapshot?

tar -zxvf file_name.tar.gz

This sounds like a corrupted file then, WinRar can open tar.gz files just fine normally.

Sure that also with password protection?

sounds obvious, but, do you know the password to open the file?

yes, i know!

Yes, but I did some research now and the tar.gz files you see, they look like tar.gz archive files, but they are not see this post here and in the same topic someone posted a python script to decrypt them.

It looks like they are not when you encrypt them with a password, see above.

Doesn’t work as they are not gzip files, see above.

So it seems there’s no “easy” way to extract any files when you password protect the backup, only by using the python script.

when you execute:

file some_backup_file.tar.gz

you’ll see that they are of type “data” and not gzip/archive.

It is the question and problem that i try to solve.
Dissapointing, that i have backup and password and can not use it (((

You can use the backup and restore it, you can just not easily extract single files.
But you can do it with the python script that I linked to.

Here’s how you can do it on the Pi:

In the folder where the .tar (not the extracted .tar.gz files) file is, create a new file decrypt.py

nano decrypt.py

Paste the following:

#!/usr/bin/env python3

import sys
import getopt
import hashlib
import tarfile
import glob
import os
import shutil

from pathlib import Path

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import (
    Cipher,
    algorithms,
    modes,
)

def _password_to_key(password):
    password = password.encode()
    for _ in range(100):
        password = hashlib.sha256(password).digest()
    return password[:16]

def _generate_iv(key, salt):
    temp_iv = key + salt
    for _ in range(100):
        temp_iv = hashlib.sha256(temp_iv).digest()
    return temp_iv[:16]

class SecureTarFile:
    def __init__(self, filename, password):
        self._file = None
        self._name = Path(filename)

        self._tar = None
        self._tar_mode = "r|gz"

        self._aes = None
        self._key = _password_to_key(password)

        self._decrypt = None

    def __enter__(self):
        self._file = self._name.open("rb")

        cbc_rand = self._file.read(16)

        self._aes = Cipher(
            algorithms.AES(self._key),
            modes.CBC(_generate_iv(self._key, cbc_rand)),
            backend=default_backend(),
        )

        self._decrypt = self._aes.decryptor()

        self._tar = tarfile.open(fileobj=self, mode=self._tar_mode)
        return self._tar

    def __exit__(self, exc_type, exc_value, traceback):
        if self._tar:
            self._tar.close()
        if self._file:
            self._file.close()

    def read(self, size = 0):
        return self._decrypt.update(self._file.read(size))

    @property
    def path(self):
        return self._name

    @property
    def size(self):
        if not self._name.is_file():
            return 0
        return round(self._name.stat().st_size / 1_048_576, 2)  # calc mbyte

def _extract_tar(filename):
    _dirname = '.'.join(filename.split('.')[:-1])

    try:
        shutil.rmtree('_dirname')
    except FileNotFoundError:
        pass

    print(f'Extracting {filename}...')
    _tar  = tarfile.open(name=filename, mode="r")
    _tar.extractall(path=_dirname)

    return _dirname

def _extract_secure_tar(filename, password):
    _dirname = '.'.join(filename.split('.')[:-2])
    print(f'Extracting secure tar {filename.split("/")[-1]}...')
    try:
        with SecureTarFile(filename, password) as _tar:
            _tar.extractall(path=_dirname)
    except tarfile.ReadError:
        print("Unable to extract SecureTar - maybe your password is wrong or the tar is not password encrypted?")
        sys.exit(5)

    return _dirname

def print_usage():
    print(f'{sys.argv[0]} -i <inputfile> -p <password>')

def main():
    _inputfile = None
    _password=None

    try:
        opts, args = getopt.getopt(sys.argv[1:],"hi:p:")
    except getopt.GetoptError:
        print_usage()
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print_usage()
            sys.exit()
        elif opt in ("-i"):
            _inputfile = arg
        elif opt in ("-p"):
            _password = arg

    if not _inputfile:
        print ("Missing inputfile")
        print_usage()
        sys.exit(3)

    if not _password:
        print ("Missing password")
        print_usage()
        sys.exit(4)

    _dirname = _extract_tar(_inputfile)
    for _secure_tar in glob.glob(f'{_dirname}/*.tar.gz'):
        _extract_secure_tar(_secure_tar, _password)
        os.remove(_secure_tar)

    print("Done")

if __name__ == "__main__":
    main()

and save the file by pressing Ctrl + X and then type y and press enter.

Then execute the following command.

python3 decrypt.py -i name-of-your-file.tar -p yourpassword

Done.

18 Likes

Thanks a lot!!! Will try

Thanks @Burningstone, works great!

I am running the above command in the terminal/shell on my RPi, but it is producing a bash: python3: command not found error. Can anyone offer some advice on why python3 is not found and how to correct this?

Probably python3 is not installed on this system. Google is your friend on how to install python3

Pretty neet indeed.

However it failed in my case.

Maybe something’s change since the writing of the script in 2019?

I systematically got a “Unable to extract SecureTar - Maybe your password is wrong or the tar is not password encrypted?” message even on freshly created backups .

Scratch that: I’m an idiot and was using the wrong password. :blush:
The script is fine and useful!
Although I decided to avoid encryption from now on.

1 Like

you are a life saver. Thanks so much

Anyone who can tell me how to do this in windows?
Have installed python3 but dont know how to use it.

follow the instructions above, but in a cmd indow instead of the nano command use notepad (or your favorite text editor) and use that to create your decrypt.py file

install the cryptography module by doing:
pip install cryptography

then run the same python command above, but your executable might be python or py instead of python3.

1 Like

Thanks a ton. This worked perfectly when all home-assistant would do on a partial backup was hang or error out.

I was pulling my hair out trying to get files out of a password protected backup. It was a long journey of not getting why other tar unpackers would not unpack the tar even with the password. Many thanks for this script worked a charm in WSL :slight_smile: