2020-05-23 07:01:54 +00:00
# Extract TOTP/HOTP secret keys from Google Authenticator
2022-09-03 16:53:23 +00:00
[![CI Status ](https://github.com/scito/extract_otp_secret_keys/actions/workflows/ci.yml/badge.svg )](https://github.com/scito/extract_otp_secret_keys/actions/workflows/ci.yml)
2022-12-30 01:01:10 +00:00
![coverage ](https://img.shields.io/badge/coverage-95%25-brightgreen )
2022-12-30 01:20:19 +00:00
[![docker ](https://github.com/scito/extract_otp_secret_keys/actions/workflows/ci_docker.yml/badge.svg )](https://github.com/scito/extract_otp_secret_keys/actions/workflows/ci_docker.yml)
2022-09-03 16:53:23 +00:00
![PyPI - Python Version ](https://img.shields.io/pypi/pyversions/protobuf )
2022-09-04 20:05:20 +00:00
[![GitHub Pipenv locked Python version ](https://img.shields.io/github/pipenv/locked/python-version/scito/extract_otp_secret_keys )](https://github.com/scito/extract_otp_secret_keys/blob/master/Pipfile.lock)
2022-12-16 12:17:39 +00:00
![protobuf version ](https://img.shields.io/badge/protobuf-4.21.12-informational )
2022-09-04 20:05:20 +00:00
[![License ](https://img.shields.io/github/license/scito/extract_otp_secret_keys )](https://github.com/scito/extract_otp_secret_keys/blob/master/LICENSE)
[![GitHub tag (latest SemVer) ](https://img.shields.io/github/v/tag/scito/extract_otp_secret_keys?sort=semver&label=version )](https://github.com/scito/extract_otp_secret_keys/tags)
2022-09-09 16:50:10 +00:00
[![Stand With Ukraine ](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg )](https://stand-with-ukraine.pp.ua)
2020-05-23 07:01:54 +00:00
2022-09-03 16:53:23 +00:00
---
2022-09-03 14:20:51 +00:00
2022-12-30 11:37:05 +00:00
TODO add src/
TODO rename extract_otp_secret_keys
2022-12-10 11:23:13 +00:00
Extract two-factor authentication (2FA, TFA, OTP) secret keys from export QR codes of "Google Authenticator" app.
2022-09-04 06:57:12 +00:00
The secret and otp values can be printed and exported to json or csv. The QR codes can be printed or saved as PNG images.
2022-09-03 14:20:51 +00:00
2022-12-10 11:23:13 +00:00
## Installation
git clone https://github.com/scito/extract_otp_secret_keys.git
cd extract_otp_secret_keys
2020-05-23 07:01:54 +00:00
## Usage
2022-12-28 21:28:54 +00:00
### Capture QR codes from camera
1. Open "Google Authenticator" app on the mobile phone
2. Export the QR codes from "Google Authenticator" app
3. Point the QR codes to the camera of your computer
4. Call this script with the file as input:
python extract_otp_secret_keys.py
### With builtin QR decoder from image files
2022-12-24 04:12:52 +00:00
1. Open "Google Authenticator" app on the mobile phone
2. Export the QR codes from "Google Authenticator" app
4. Save the captured QR codes as image files, e.g. example_export.png
5. Transfer the images files to the computer where his script is installed.
6. Call this script with the file as input:
python extract_otp_secret_keys.py example_export.png
2022-12-28 21:28:54 +00:00
### With external QR decoder app from text files
2022-12-24 04:12:52 +00:00
2022-10-30 13:44:46 +00:00
1. Open "Google Authenticator" app on the mobile phone
2. Export the QR codes from "Google Authenticator" app
3. Read QR codes with a QR code reader (e.g. from another phone)
4. Save the captured QR codes in the QR code reader to a text file, e.g. example_export.txt. Save each QR code on a new line. (The captured QR codes look like `otpauth-migration://offline?data=...` )
5. Transfer the file to the computer where his script is installed.
6. Call this script with the file as input:
2020-05-23 07:30:47 +00:00
2022-12-10 11:23:13 +00:00
python extract_otp_secret_keys.py example_export.txt
2022-09-08 19:11:49 +00:00
## Program help: arguments and options
2022-12-28 21:28:54 +00:00
< pre > usage: extract_otp_secret_keys.py [-h] [--camera NUMBER] [--json FILE] [--csv FILE] [--keepass FILE] [--printqr] [--saveqr DIR] [--verbose | --quiet] [infile ...]
Extracts one time password (OTP) secret keys from QR codes, e.g. from Google Authenticator app.
If no infiles are provided, the QR codes are interactively captured from the camera.
2022-09-08 19:11:49 +00:00
positional arguments:
2022-12-28 21:28:54 +00:00
infile a) file or - for stdin with 'otpauth-migration://...' URLs separated by newlines, lines starting with # are ignored;
b) image file containing a QR code or = for stdin for an image containing a QR code
2022-09-08 19:11:49 +00:00
options:
2022-12-28 21:28:54 +00:00
-h, --help show this help message and exit
--camera NUMBER, -C NUMBER camera number of system (default camera: 0)
--json FILE, -j FILE export json file or - for stdout
--csv FILE, -c FILE export csv file or - for stdout
--keepass FILE, -k FILE export totp/hotp csv file(s) for KeePass, - for stdout
--printqr, -p print QR code(s) as text to the terminal (requires qrcode module)
--saveqr DIR, -s DIR save QR code(s) as images to the given folder (requires qrcode module)
--verbose, -v verbose output
--quiet, -q no stdout output, except output set by -
2022-12-26 23:43:30 +00:00
examples:
2022-12-28 21:28:54 +00:00
python extract_otp_secret_keys.py
2022-12-26 23:43:30 +00:00
python extract_otp_secret_keys.py example_*.txt
python extract_otp_secret_keys.py - < example_export.txt
python extract_otp_secret_keys.py --csv - example_*.png | tail -n+2
python extract_otp_secret_keys.py = < example_export.png < / pre >
2020-05-23 07:01:54 +00:00
2022-08-29 16:29:01 +00:00
## Dependencies
2020-05-23 07:01:54 +00:00
2022-09-03 12:31:09 +00:00
pip install -r requirements.txt
2020-05-23 07:01:54 +00:00
2022-12-24 04:31:17 +00:00
Known to work with
* Python 3.10.8, protobuf 4.21.9, qrcode 7.3.1, and pillow 9.2
* Python 3.11.1, protobuf 4.21.12, qrcode 7.3.1, and pillow 9.2
For protobuf versions 3.14.0 or similar or Python 3.6, use the extract_otp_secret_keys version 1.4.0.
2022-12-24 14:30:17 +00:00
### Shared libs installation for reading QR code images
2022-12-24 01:37:16 +00:00
2022-12-24 14:30:17 +00:00
For reading QR code images the zbar library must be installed.
If you do not extract directly from images, you do not need to install the zbar shared library.
2022-12-24 04:31:17 +00:00
2022-12-24 14:30:17 +00:00
For a detailed installation documentation of [pyzbar ](https://github.com/NaturalHistoryMuseum/pyzbar#installation ).
2022-12-24 01:37:16 +00:00
#### Windows
The zbar DLLs are included with the Windows Python wheels. On other operating systems, you will need to install the zbar shared library.
2022-12-24 04:31:17 +00:00
#### Linux (Debian, Ubuntu, ...)
2022-12-24 01:37:16 +00:00
sudo apt-get install libzbar0
2022-12-24 04:31:17 +00:00
#### Linux (OpenSUSE)
2021-02-07 19:01:56 +00:00
2022-12-24 14:30:17 +00:00
sudo zypper install libzbar0
2021-02-07 19:01:56 +00:00
2022-12-24 04:31:17 +00:00
#### Linux (Fedora)
sudo dnf install libzbar0
2022-09-04 06:57:12 +00:00
2022-12-24 14:30:17 +00:00
#### Mac OS X
brew install zbar
2022-12-24 00:59:35 +00:00
## Examples
2020-05-23 07:01:54 +00:00
2022-12-24 00:59:35 +00:00
### Printing otp secrets form text file
2020-05-23 07:01:54 +00:00
2022-12-24 00:59:35 +00:00
python extract_otp_secret_keys.py example_export.txt
2022-12-24 04:12:52 +00:00
### Printing otp secrets from image file
2022-12-24 00:59:35 +00:00
2022-12-24 04:12:52 +00:00
python extract_otp_secret_keys.py example_export.png
### Printing otp secrets multiple files
2022-12-24 00:59:35 +00:00
2022-12-24 04:12:52 +00:00
python extract_otp_secret_keys.py example_*.txt
python extract_otp_secret_keys.py example_*.png
python extract_otp_secret_keys.py example_export.*
python extract_otp_secret_keys.py example_*.txt example_*.png
2022-12-24 00:59:35 +00:00
2022-12-24 04:12:52 +00:00
### Printing otp secrets from stdin (text)
python extract_otp_secret_keys.py - < example_export.txt
2022-12-24 00:59:35 +00:00
### Printing otp secrets from stdin (image)
2022-12-24 04:12:52 +00:00
python extract_otp_secret_keys.py = < example_export.png
2022-12-24 00:59:35 +00:00
### Printing otp secrets csv to stdout
python extract_otp_secret_keys.py --csv - example_export.txt
2020-05-23 07:01:54 +00:00
2022-12-24 14:50:44 +00:00
### Printing otp secrets csv to stdout without header line
python extract_otp_secret_keys.py --csv - example_*.png | tail -n+2
### Reading from stdin and printing to stdout
cat example_*.txt | python extract_otp_secret_keys.py --csv - - | tail -n+2
2022-12-10 11:23:13 +00:00
## Features
* Free and open source
2022-12-24 04:12:52 +00:00
* Supports Google Authenticator exports (and compatible apps like Aegis Authenticator)
2022-12-30 01:20:19 +00:00
* Captures the the QR codes directly from the camera using QR code detection (based on OpenCV)
2022-12-10 11:23:13 +00:00
* Supports TOTP and HOTP
* Generates QR codes
2022-12-24 14:50:44 +00:00
* Exports to various formats:
2022-12-10 11:23:13 +00:00
* CSV
* JSON
* Dedicated CSV for KeePass
* QR code images
2022-12-24 14:50:44 +00:00
* Supports reading from stdin and writing to stdout
2022-12-30 01:20:19 +00:00
* Reads QR codes images: (See [OpenCV docu ](https://docs.opencv.org/3.4/d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56 ))
2022-12-24 04:12:52 +00:00
* Portable Network Graphics - *.png
* WebP - *.webp
* JPEG files - *.jpeg, * .jpg, *.jpe
* TIFF files - *.tiff, * .tif
* Windows bitmaps - *.bmp, * .dib
* JPEG 2000 files - *.jp2
* Portable image format - *.pbm, * .pgm, *.ppm * .pxm, *.pnm
* Sun rasters - *.sr, * .ras
* OpenEXR Image files - *.exr
* Radiance HDR - *.hdr, * .pic
* Raster and Vector geospatial data supported by GDAL
2022-12-18 18:24:07 +00:00
* Errors and warnings are written to stderr
2022-12-10 11:23:13 +00:00
* Many ways to run the script:
* Native Python
* pipenv
2022-12-30 01:20:19 +00:00
* pip
2022-12-10 11:23:13 +00:00
* venv
* Docker
* VSCode devcontainer
* devbox
2022-12-30 01:20:19 +00:00
* Compatible with major platforms:
2022-12-24 04:12:52 +00:00
* Linux
* macOS
* Windows
2022-12-30 01:20:19 +00:00
* Uses UTF-8 on all platforms
* Supports Python >= 3.7
* All these features are backed by tests ran nightly
* All functionality in one Python script: extract_otp_secret_keys.py (except protobuf generated code in protobuf_generated_python)
2022-12-10 11:23:13 +00:00
2022-12-04 11:23:39 +00:00
## KeePass
[KeePass 2.51 ](https://keepass.info/news/n220506_2.51.html ) (released in May 2022) and newer [support the generation of OTPs (TOTP and HOTP) ](https://keepass.info/help/base/placeholders.html#otp ).
KeePass can generate the second factor password (2FA) if the OTP secret is stored in `TimeOtp-Secret-Base32` string field for TOTP or `HmacOtp-Secret-Base32` string field for HOTP. You view or edit them in entry dialog on the 'Advanced' tab page.
KeePass provides menu commands in the main window for generating one-time passwords ('Copy HMAC-Based OTP', 'Show HMAC-Based OTP', 'Copy Time-Based OTP', 'Show Time-Based OTP'). Furthermore, one-time passwords can be generated during auto-type using the {HMACOTP} and {TIMEOTP} placeholders.
In order to simplify the usage of the second factor password generation in KeePass a specific KeePass CSV export is available with option `-keepass` or `-k` . This KeePass CSV file can be imported by the ["Generic CSV Importer" of KeePass ](https://keepass.info/help/kb/imp_csv.html ).
If TOTP and HOTP entries have to be exported, then two files with an intermediate suffix .totp or .hotp will be added to the KeePass export filename.
Example:
- Only TOTP entries to export and parameter --keepass example_keepass_output.csv< br >
→ example_keepass_output.csv with TOTP entries will be exported
- Only HOTP entries to export and parameter --keepass example_keepass_output.csv< br >
→ example_keepass_output.csv with HOTP entries will be exported
- If both TOTP and HOTP entries to export and parameter --keepass example_keepass_output.csv< br >
→ example_keepass_output.totp.csv with TOTP entries will be exported< br >
→ example_keepass_output.hotp.csv with HOTP entries will be exported
Import CSV with TOTP entries in KeePass as
- Title
- User Name
- String (TimeOtp-Secret-Base32)
- Group (/)
Import CSV with HOTP entries in KeePass as
- Title
- User Name
- String (HmacOtp-Secret-Base32)
- String (HmacOtp-Counter)
- Group (/)
KeePass can be used as a backup for one time passwords (second factor) from the mobile phone.
2020-05-23 07:01:54 +00:00
## Technical background
2020-05-23 07:30:47 +00:00
The export QR code of "Google Authenticator" contains the URL `otpauth-migration://offline?data=...` .
2020-05-23 07:01:54 +00:00
The data parameter is a base64 encoded proto3 message (Google Protocol Buffers).
2022-09-03 12:31:09 +00:00
Command for regeneration of Python code from proto3 message definition file (only necessary in case of changes of the proto3 message definition or new protobuf versions):
2022-12-29 20:29:20 +00:00
protoc --python_out=protobuf_generated_python google_auth.proto --mypy_out=protobuf_generated_python
2020-05-23 07:01:54 +00:00
2022-12-16 12:17:39 +00:00
The generated protobuf Python code was generated by protoc 21.12 (https://github.com/protocolbuffers/protobuf/releases/tag/v21.12).
2020-05-23 07:01:54 +00:00
2022-12-29 20:29:20 +00:00
https://github.com/nipunn1313/mypy-protobuf
2020-05-23 07:01:54 +00:00
## References
2020-05-23 07:03:37 +00:00
* Proto3 documentation: https://developers.google.com/protocol-buffers/docs/pythontutorial
* Template code: https://github.com/beemdevelopment/Aegis/pull/406
2022-08-29 16:29:01 +00:00
2022-12-10 11:23:13 +00:00
## Glossary
* OTP = One-time password
* TOTP = Time-based one-time password
* HOTP = HMAC-based one-time password (using a counter)
* 2FA = Second factor authentication
* TFA = Two factor authentication
* QR code = Quick response code
2022-08-29 16:29:01 +00:00
## Alternative installation methods
2022-12-10 11:23:13 +00:00
### pip
```
pip install git+https://github.com/scito/extract_otp_secret_keys
python -m extract_otp_secret_keys
```
2022-12-29 03:15:36 +00:00
#### For development
```
pip install git+https://github.com/scito/extract_otp_secret_keys@support_img_read
python -m extract_otp_secret_keys
```
```
# pip install -e git+https://github.com/scito/extract_otp_secret_keys@$(git ls-remote git@github.com:scito/extract_otp_secret_keys@support_img_read.git | head -1 | awk '{print $1;}')#egg=extract_otp_secret_keys
pip3.11 install -e git+https://github.com/scito/extract_otp_secret_keys.git@$(git ls-remote git@github.com:scito/extract_otp_secret_keys.git | grep support_img_read | head -1 | awk '{print $1;}')#egg=extract_otp_secret_keys
python -m extract_otp_secret_keys
```
2022-12-10 11:23:13 +00:00
#### Example
```
wget https://raw.githubusercontent.com/scito/extract_otp_secret_keys/master/example_export.txt
python -m extract_otp_secret_keys example_export.txt
```
2022-12-30 11:37:05 +00:00
### local pip
```
pip install -e .
```
2022-09-03 16:48:58 +00:00
### pipenv
You can you use [Pipenv ](https://github.com/pypa/pipenv ) for running extract_otp_secret_keys.
```
2022-11-27 20:47:34 +00:00
pipenv --rm
2022-09-03 16:48:58 +00:00
pipenv install
pipenv shell
python extract_otp_secret_keys.py example_export.txt
```
2022-09-04 13:58:58 +00:00
### Visual Studio Code Remote - Containers / VSCode devcontainer
You can you use [VSCode devcontainer ](https://code.visualstudio.com/docs/remote/containers-tutorial ) for running extract_otp_secret_keys.
Requirement: Docker
1. Start VSCode
2. Open extract_otp_secret_keys.code-workspace
3. Open VSCode command palette (Ctrl-Shift-P)
4. Type command "Remote-Containers: Reopen in Container"
5. Open integrated bash terminal in VSCode
6. Execute: python extract_otp_secret_keys.py example_export.txt
2022-08-29 16:29:01 +00:00
### venv
Alternatively, you can use a python virtual env for the dependencies:
python -m venv venv
. venv/bin/activate
2022-09-04 13:58:58 +00:00
pip install -r requirements-dev.txt
2022-08-29 16:29:01 +00:00
pip install -r requirements.txt
The requirements\*.txt files contain all the dependencies (also the optional ones).
To leave the python virtual env just call `deactivate` .
### devbox
Install [devbox ](https://github.com/jetpack-io/devbox ), which is a wrapper for nix. Then enter the environment with Python and the packages installed with:
```
devbox shell
```
2022-09-03 12:31:09 +00:00
2022-11-19 08:18:24 +00:00
### Docker
Install [Docker ](https://docs.docker.com/get-docker/ ).
Build and run the app within the container:
```bash
2022-12-26 17:31:09 +00:00
docker build . -t extract_otp_secret_keys --pull
docker run --rm -v "$(pwd)":/files:ro extract_otp_secret_keys example_export.txt
docker run --rm -v "$(pwd)":/files:ro extract_otp_secret_keys example_export.png
2022-11-19 08:18:24 +00:00
```
2022-12-26 17:31:09 +00:00
docker run --rm -v "$(pwd)":/files:ro -i extract_otp_secret_keys = < example_export.png
2022-12-29 03:15:36 +00:00
docker run --rm -v "$(pwd)":/files:ro -i --device="/dev/video0:/dev/video0" --env="DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix:ro extract_otp_secret_keys
docker run --pull always --rm -v "$(pwd)":/files:ro -i --device="/dev/video0:/dev/video0" --env="DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix:ro scit0/extract_otp_secret_keys
2022-12-26 17:31:09 +00:00
docker run --entrypoint /bin/bash -it --rm -v "$(pwd)":/files:ro extract_otp_secret_keys
2022-12-29 02:19:09 +00:00
docker run --pull always --rm -v "$(pwd)":/files:ro -i scit0/extract_otp_secret_keys
2022-12-26 17:31:09 +00:00
2022-12-28 21:28:54 +00:00
docker login -uscit0
2022-12-26 17:31:09 +00:00
docker build . -t extract_otp_secret_keys_no_qr_reader -f Dockerfile_no_qr_reader --pull
2022-12-29 00:48:00 +00:00
docker build . -t extract_otp_secret_keys_no_qr_reader -f Dockerfile_no_qr_reader --pull --build-arg RUN_TESTS=false
2022-12-29 01:34:29 +00:00
docker run --entrypoint /extract/run_pytest.sh --rm -v "$(pwd)":/files:ro scit0/extract_otp_secret_keys_no_qr_reader test_extract_otp_secret_keys_pytest.py -k "not qreader" --relaxed
2022-12-26 17:31:09 +00:00
docker run --rm -v "$(pwd)":/files:ro extract_otp_secret_keys_no_qr_reader example_export.txt
docker run --rm -v "$(pwd)":/files:ro -i extract_otp_secret_keys_no_qr_reader - < example_export.txt
docker build . -t extract_otp_secret_keys_no_qr_reader -f Dockerfile_no_qr_reader --pull & & docker run --entrypoint /extract/run_pytest.sh --rm -v "$(pwd)":/files:ro extract_otp_secret_keys_no_qr_reader test_extract_otp_secret_keys_pytest.py -k "not qreader" -vvv --relaxed -s
2022-12-26 23:43:30 +00:00
docker pull scit0/extract_otp_secret_keys
docker pull scit0/extract_otp_secret_keys_no_qr_reader
docker pull ghcr.io/scito/extract_otp_secret_keys
docker pull ghcr.io/scito/extract_otp_secret_keys_no_qr_reader
2022-09-03 13:38:47 +00:00
## Tests
### PyTest
2022-09-03 21:47:43 +00:00
There are basic [pytest ](https://pytest.org )s, see `test_extract_otp_secret_keys_pytest.py` .
2022-09-03 13:38:47 +00:00
2022-09-03 16:53:23 +00:00
Run tests:
2022-09-03 13:38:47 +00:00
```
2022-09-03 21:47:43 +00:00
pytest
2022-09-03 13:38:47 +00:00
```
or
```
python -m pytest
```
2022-09-03 16:53:23 +00:00
2022-12-30 11:37:05 +00:00
#### Hints
Your tests can run against an installed version after executing pip install .
Your tests can run against the local copy with an editable install after executing pip install --editable .
If you don’ t use an editable install and are relying on the fact that Python by default puts the current directory in sys.path to import your package, you can execute python -m pytest to execute the tests against the local copy directly, without using pip.
https://docs.pytest.org/en/7.1.x/explanation/pythonpath.html#pytest-vs-python-m-pytest
2022-09-03 16:53:23 +00:00
### unittest
2022-09-03 21:47:43 +00:00
There are basic [unittest ](https://docs.python.org/3.10/library/unittest.html )s, see `test_extract_otp_secret_keys_unittest.py` .
2022-09-03 16:53:23 +00:00
2022-09-03 21:47:43 +00:00
Run tests:
2022-09-03 16:53:23 +00:00
```
python -m unittest
```
2022-09-04 19:02:36 +00:00
### VSCode Setup
Setup for running the tests in VSCode.
1. Open VSCode command palette (Ctrl-Shift-P)
2. Type command "Python: Configure Tests"
3. Choose unittest or pytest. (pytest is recommended, both are supported)
4. Set ". Root" directory
2022-09-09 16:50:10 +00:00
2022-12-30 11:37:05 +00:00
## Development
### Build
```
pip install -e .
python src/extract_otp_secret_keys.py
pip wheel .
# --isolated
# --prefer-binary
python3.11 -m build --wheel
# =
pip wheel --no-deps .
```
2022-09-25 09:54:22 +00:00
### Upgrade pip Packages
```
pip install -U -r requirements.txt
```
2022-12-10 11:23:13 +00:00
## Related projects
* [ZBar ](https://github.com/mchehab/zbar ) is an open source software suite for reading bar codes from various sources, including webcams.
* [Aegis Authenticator ](https://github.com/beemdevelopment/Aegis ) is a free, secure and open source 2FA app for Android.
* [Android OTP Extractor ](https://github.com/puddly/android-otp-extractor ) can extract your tokens from popular Android OTP apps and export them in a standard format or just display them as QR codes for easy importing. [Requires a _rooted_ Android phone.]
2022-12-24 01:29:43 +00:00
* [Python QReader ](https://github.com/Eric-Canas/QReader )
* [pyzbar ](https://github.com/NaturalHistoryMuseum/pyzbar )
2022-12-10 11:23:13 +00:00
2022-09-09 16:50:10 +00:00
***
# #StandWithUkraine 🇺🇦
I have Ukrainian relatives and friends.
#RussiaInvadedUkraine on 24 of February 2022, at 05:00 the armed forces of the Russian Federation attacked Ukraine. Please, stand with Ukraine, stay tuned for updates on Ukraine's official sources and channels in English and support Ukraine in its fight for freedom and democracy in Europe.