Git Product home page Git Product logo

bitwardendecrypt's Introduction

BitwardenDecrypt

Decrypts an encrypted Bitwarden data.json file (from the Desktop App).
You can safely store data.json as an encrypted, offline backup of your vault knowing you will always be able to decrypt it.

To determine the location of the data.json file see:
https://bitwarden.com/help/data-storage/#on-your-local-machine

Note: BitwardenDecrypt does not work with Bitwarden Encrypted JSON Exports.
These exports lack the Protected Symmetric Key needed to decrypt entries.

Password Protected Encrypted JSON Exports are supported.


Outputs JSON containing:

  • Logins
  • Folders
  • Organizations
  • Collections
  • Cards
  • Secure Notes
  • Identities
  • Sends (Optional)

Note: Outputs (almost) all key/value pairs, including ones you probably don't care about.

Usage:

./BitwardenDecrypt.py [options]  (reads data.json from current directory)
or
./BitwardenDecrypt.py [options] inputfile

Password: (Enter Password)

Options:
        --includesends          Include Sends in the output.
        --output OUTPUTFILE     Write decrypted output to file.
                                Will overwrite contents if file exists.

On Windows:

py BitwardenDecrypt.py [options]
or
py BitwardenDecrypt.py [options] inputfile

Password: (Enter Password)

Options:
        --includesends          Include Sends in the output.
        --output OUTPUTFILE     Write decrypted output to file.
                                Will overwrite contents if file exists.

Note: This script depends on the 'cryptography' package
pip install cryptography

Donate

Find this useful? If so, consider showing your appreciation. πŸ™‚
https://paypal.me/GurpreetKang


Limitations

  • Attachments are not supported (they are not stored locally in data.json)
  • Does not work with Bitwarden Encrypted JSON Exports.
    These exports lack the Protected Symmetric Key needed to decrypt entries.
    (Password Protected Encrypted JSON Exports are now supported)
  • No validation of the CipherString. I.e. No verification of the MAC before decrypting. Now verifies the MAC.
  • Can only decrypt EncryptionType: 2 (AesCbc256_HmacSha256_B64). At the time of writing this is the default used for all entries in the personal vault.
  • Does not decrypt anything from a Collection (Organization).
    Initial support for decrypting items from a Collection (Organization). This adds support for decrypting EncryptionType: 4 (Rsa2048_OaepSha1_B64)

To Do

[ ] Nothing. Hopefully Bitwarden will implement an encrypted export and this script can become obsolete.

License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details

Acknowledgments

This project is not associated with Bitwarden or Bitwarden, Inc.

bitwardendecrypt's People

Contributors

gurpreetkang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

bitwardendecrypt's Issues

Without --output option, prints a Python bytes literal instead of the raw data

When using without the --output option, it prints a Python bytes literal string containing the JSON to stdout like (truncated):

b'{\n  "folders": [\n    {\n      "id":  ...

I think print(decryptedJSON.encode("utf-8")) needs to be changed to just print(decryptedJSON) (L601).
It looks like you were trying to ensure output is UTF-8 encoded. I think the way to do this is calling sys.stdout.reconfigure(encoding='utf-8') before the print call. (See https://stackoverflow.com/questions/4374455/how-to-set-sys-stdout-encoding-in-python-3 for this and other ways to do this).
Or, leave it up to the user to set the encoding they want (e.g. they can control this independently of your script by using the PYTHONIOENCODING environment variable, or configuring their system). In practice, this is often an issue for Windows users because the default encoding in the terminal is not always UTF-8, but on other platforms the encoding is usually set to a sane default. So you could special-case Windows and leave the stdout encoding as is on other platforms.

Code has Windows/DOS-style line endings which must be converted before running on Linux

Hi, when I ran this for the first time on a Linux machine (Debian 11), I got the error
/usr/bin/env: β€˜python3\r’: No such file or directory
This indicates the "file was created or edited on a Windows system and uses Windows/DOS-style line endings (CR+LF), whereas Linux systems ... require Unix-style line endings (LF)." (source)
Per the suggestion in that post, I was able to fix this after running dos2unix on the file, after which the file executed perfectly.
I believe this means that at some point the python code was saved on a Windows machine? I have not tested running the file on Windows, however if the intention is to generally run it on Linux then it may be best to save on Linux before pushing to github.
If I am missing something, let me know. Thank you!

Reason for `ast.literal_eval`?

Issue #1 was originally created by @irgeek, but was accidentally deleted by me. πŸ™

groupData = json.loads(json.dumps(datafile[a]))

I noticed while perusing the code that you seem to be turning parts of the already-decoded JSON into string and evaluating them as Python with the ast.literal_eval method. What's the reason for this? It's common practice to avoid eval whenever possible, and this specific usage appears to do nothing more than inefficiently copy a data structure.

Attachment 'key' value does not decrypt, and causes the current version V1.3 of BitwardenDecrypt to crash.

This is an issue filed after going back and forth with GurpreetKang on Reddit a few times, and just documenting the issue and what we went through and discovered in the process.

With the (as of writing) currently available version, v1.3, setup with Python 3.9.7 (also tried it with 3.10 and 3.8), in a venv created specifically for this, after running pip install -r requirements.txt, then running the program in PowerShell or CMD with the venv active (to rule out any other installed packages or dependencies), it gives the following error:

❯ .\BitwardenDecrypt.py
Password:
Traceback (most recent call last):
  File "E:\Projects\Repos\BitwardenDecrypt\BitwardenDecrypt.py", line 325, in <module>
    main()
  File "E:\Projects\Repos\BitwardenDecrypt\BitwardenDecrypt.py", line 320, in main
    decryptedJSON = decryptBitwardenJSON(inputfile)
  File "E:\Projects\Repos\BitwardenDecrypt\BitwardenDecrypt.py", line 299, in decryptBitwardenJSON
    jsonEscapedString = json.JSONEncoder().encode(decryptCipherString(match, encKey, macKey))
  File "E:\Projects\Repos\BitwardenDecrypt\BitwardenDecrypt.py", line 216, in decryptCipherString
    return(cleartext.decode('utf-8'))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa0 in position 0: invalid start byte

Now, 0xa0 is a "non-returning space". I don't think this is relevant as even switching it to a different attachment by reordering the data.json file, regardless of what you do it still causes issues with various bytes that it considers invalid start bytes.

I made a minor modification to the code to print out the cleartext variable in the decryptCipherString function, to see what the last item was before it errored out, and it turned out to be the first instance of an attachment's key.
GurpreetKang then sent me a couple of versions to do some debugging with, and every instance of an attachments key was failing to decrypt. This indicates that it is almost certainly encrypted in a different way to the rest of the file.

KeyError: 'encrypted'

Hello. I bumped in the following error when executing BitwardenDecrypt

  File "/home/$USER/build/BitwardenDecrypt/BitwardenDecrypt.py", line 604, in <module>
    main(args)
  File "/home/$USER/build/BitwardenDecrypt/BitwardenDecrypt.py", line 585, in main
    decryptedJSON = decryptBitwardenJSON(options)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/$USER/build/BitwardenDecrypt/BitwardenDecrypt.py", line 394, in decryptBitwardenJSON
    email, kdfIterations, encKey, encPrivateKey = checkFileFormatVersion(options)
                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/$USER/build/BitwardenDecrypt/BitwardenDecrypt.py", line 362, in checkFileFormatVersion
    encKey = datafile[options.account['UUID']]['keys']['cryptoSymmetricKey']['encrypted']
             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
KeyError: 'encrypted'

I start application as python3 BitwardenDecrypt.py ./data.json
My Bitwarden desktop app version: 2023.10.1
I run on linux

Add support for downloading/decrypting file attachments.

Add support for downloading encrypted file attachments and decrypting them using the unique per-attachment Protected Symmetric Key.

As BitwardenDecrypt is intended to be backup in case Bitwarden is not available (down, no longer in business, etc.) support for file attachments may be of limited use. If Bitwarden is available, attachments can be accessed using the official apps (though at the time of writing there is no easy way using the official apps to backup/download all attachments). If Bitwarden is unavailable any download/decryption of file attachments will fail.

Bitwarden Desktop 1.30.0+ data.json files can not be decrypted.

Bitwarden Desktop 1.30.0+ adds an account switching feature and associated changes to the data.json structure which breaks BitwardenDecrypt.

The previously used "userEmail" name/value pair is no longer present, replaced with potentially multiple "email" name/value pairs.

Additional changes to the data structure are also present in 1.30.0+ data.json files.

Is this meant to work for organization backups?

Hi, I created an encrypted export using this command subprocess'bw', 'export', '--organizationid', org_id, '--output', enc_output_file, '--format', 'encrypted_json'. From my understanding this is the same as manually creating an org vault backup from web.

In the event that Bitwarden is down, and I want to decrypted my data.json export and read passwords, how can I do that.

When I try this software I get a key error: email = options.account['email'] KeyError: 'email'.

Handle Unsupported EncryptionType Gracefully

Decryption of the Protected Symmetric Key assumes the EncryptionType = 2 (AesCbc256_HmacSha256_B64) and will fail if it is anything else.
Old Bitwarden accounts may be using EncryptionType = 0 (AesCbc256_B64)

This should be handled gracefully with a meaningful error message.

Docker image?

That would be great to have a docker image for such a useful tool

Add support for decrypting Sends

Add support for decrypting Sends, which have unique per-item Protected Symmetric Key.
Currently any Sends in the data.json file are ignored and not included in the output.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.