fiddlesticks 0.3.0__tar.gz → 0.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. fiddlesticks-0.6.0/.gitattributes +5 -0
  2. fiddlesticks-0.6.0/.github/workflows/benchmarks.yml +72 -0
  3. fiddlesticks-0.6.0/.github/workflows/build_test_env.yml +73 -0
  4. fiddlesticks-0.6.0/.github/workflows/dev_tests.yml +76 -0
  5. fiddlesticks-0.6.0/.github/workflows/tests.yml +38 -0
  6. {fiddlesticks-0.3.0 → fiddlesticks-0.6.0}/.gitignore +3 -0
  7. fiddlesticks-0.6.0/Dockerfile +55 -0
  8. fiddlesticks-0.3.0/README.md → fiddlesticks-0.6.0/PKG-INFO +70 -12
  9. fiddlesticks-0.3.0/PKG-INFO → fiddlesticks-0.6.0/README.md +41 -29
  10. fiddlesticks-0.6.0/benchmarks.py +215 -0
  11. fiddlesticks-0.6.0/dev/Candidate_iteration_11.6h_estimate.ods +0 -0
  12. fiddlesticks-0.6.0/dev/pw_generator_regression_tests.py +142 -0
  13. fiddlesticks-0.6.0/dev/sketch_multicore.py +162 -0
  14. fiddlesticks-0.6.0/fiddlesticks_benchmarks.txt +7 -0
  15. {fiddlesticks-0.3.0 → fiddlesticks-0.6.0}/pyproject.toml +27 -7
  16. fiddlesticks-0.6.0/src/fiddlesticks.py +1444 -0
  17. fiddlesticks-0.6.0/tests/checker_tests.py +206 -0
  18. fiddlesticks-0.6.0/tests/data_files/Test_vault_Do_Not_Use.kdbx +0 -0
  19. fiddlesticks-0.6.0/tests/data_files/test.docx +0 -0
  20. fiddlesticks-0.6.0/tests/data_files/test.xlsx +0 -0
  21. {fiddlesticks-0.3.0 → fiddlesticks-0.6.0}/tests/end_to_end_tests.py +158 -32
  22. {fiddlesticks-0.3.0 → fiddlesticks-0.6.0}/tests/helpers.py +144 -4
  23. fiddlesticks-0.6.0/tests/misc_tests.py +291 -0
  24. fiddlesticks-0.6.0/tests/pw_generator_tests.py +264 -0
  25. fiddlesticks-0.3.0/.gitattributes +0 -2
  26. fiddlesticks-0.3.0/.github/workflows/tests.yml +0 -27
  27. fiddlesticks-0.3.0/src/fiddlesticks.py +0 -693
  28. fiddlesticks-0.3.0/tests/Test_vault_Do_Not_Use.kdbx +0 -0
  29. fiddlesticks-0.3.0/tests/checker_tests.py +0 -75
  30. fiddlesticks-0.3.0/tests/pw_generator_tests.py +0 -66
  31. {fiddlesticks-0.3.0 → fiddlesticks-0.6.0}/.github/workflows/lint.yml +0 -0
  32. {fiddlesticks-0.3.0 → fiddlesticks-0.6.0}/.pre-commit-config.yaml +0 -0
  33. {fiddlesticks-0.3.0 → fiddlesticks-0.6.0}/CANARY +0 -0
  34. {fiddlesticks-0.3.0 → fiddlesticks-0.6.0}/LICENSE +0 -0
  35. {fiddlesticks-0.3.0 → fiddlesticks-0.6.0}/tests/__init__.py +0 -0
  36. {fiddlesticks-0.3.0/tests → fiddlesticks-0.6.0/tests/data_files}/foo.7z +0 -0
@@ -0,0 +1,5 @@
1
+ * text eol=lf
2
+ *.kdbx binary
3
+ *.7z binary
4
+ *.docx binary
5
+ *.xlsx binary
@@ -0,0 +1,72 @@
1
+ name: Benchmarks
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ jobs:
7
+ test:
8
+ runs-on: ubuntu-latest
9
+ container:
10
+ image: ubuntu:26.04
11
+ # These are needed to run libfuse and mount
12
+ # drives within the container for Veracrypt
13
+ options: >-
14
+ --device /dev/fuse
15
+ --cap-add SYS_ADMIN
16
+ --security-opt apparmor:unconfined
17
+ --privileged
18
+ -v /dev:/dev
19
+ steps:
20
+ - name: Check out repo
21
+ uses: actions/checkout@v7
22
+
23
+
24
+ - name: Check Git hasn't corrupted test data files
25
+ run: |
26
+ sha256sum tests/data_files/Test_vault_Do_Not_Use.kdbx
27
+
28
+ - name: Install deps
29
+ run: |
30
+ apt-get update
31
+ apt-get install -y sudo wget git 7zip python3-venv python3-pip python-is-python3
32
+
33
+
34
+ - name: Direct Install libfuse3-4
35
+ run: |
36
+ sudo apt-get update && sudo apt-get install -y wget
37
+ wget http://archive.ubuntu.com/ubuntu/pool/main/f/fuse3/libfuse3-4_3.18.2-1_amd64.deb
38
+ sudo dpkg -i libfuse3-4_3.18.2-1_amd64.deb || sudo apt-get install -f -y
39
+
40
+ - name: Download Veracrypt .deb
41
+ run: wget https://github.com/veracrypt/VeraCrypt/releases/download/VeraCrypt_1.26.29/veracrypt-console-1.26.29-Ubuntu-26.04-amd64.deb
42
+
43
+ - name: Install Veracrypt from downloaded .deb
44
+ run: |
45
+ sudo apt update
46
+ sudo apt install -y software-properties-common
47
+ sudo add-apt-repository universe
48
+ sudo apt-get update
49
+ # Suggests fuse3
50
+ sudo apt-get install -y fuse3 libfuse3-dev
51
+ sudo apt-get install -y ./veracrypt-console-1.26.29-Ubuntu-26.04-amd64.deb
52
+
53
+
54
+
55
+ - name: Create venv
56
+ run: |
57
+ python3 -m venv .venv
58
+
59
+ - name: Install dependencies
60
+ run: |
61
+ . ./.venv/bin/activate
62
+ pip install -e . --group=all_optional_deps
63
+
64
+
65
+ - name: Run Benchmarks
66
+ run: |
67
+ . ./.venv/bin/activate
68
+ python benchmarks.py --output-file benchmarks.txt --max-time-s=3540 --max-num-subs=6
69
+
70
+ - name: Print Benchmark results file
71
+ run: |
72
+ cat benchmarks.txt
@@ -0,0 +1,73 @@
1
+ name: Build docker image for the test environment
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+
7
+ permissions:
8
+ contents: read
9
+ packages: write
10
+
11
+ jobs:
12
+ build_test_env:
13
+ runs-on: ubuntu-26.04
14
+
15
+ steps:
16
+ - name: Check out repo
17
+ uses: actions/checkout@v7
18
+
19
+ - name: Set up Docker Buildx
20
+ uses: docker/setup-buildx-action@v4
21
+
22
+ # Only login if workflow trigger is NOT a PR from a fork.
23
+ - name: Log in to GHCR
24
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
25
+ uses: docker/login-action@v4
26
+ with:
27
+ registry: ghcr.io
28
+ username: ${{ github.actor }}
29
+ password: ${{ secrets.GITHUB_TOKEN }}
30
+
31
+ - name: Extract Docker metadata
32
+ id: docker_metadata
33
+ uses: docker/metadata-action@v6
34
+ with:
35
+ images: ghcr.io/${{ github.repository }}/test_env
36
+ tags: |
37
+ type=ref,event=branch
38
+ type=ref,event=pr
39
+ type=sha,format=short
40
+
41
+ - name: Build and Push Docker Image
42
+ uses: docker/build-push-action@v7
43
+ with:
44
+ context: .
45
+ file: Dockerfile
46
+ build-args: |
47
+ INSTALL_7Z=true
48
+ INSTALL_VERACRYPT=true
49
+ TEST_ENV=true
50
+ tags: ${{ steps.docker_metadata.outputs.tags }}
51
+ # Only push to the registry if it's a branch push or internal PR.
52
+ push: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
53
+ # Otherwise, only load, so the image builds locally for testing.
54
+ load: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }}
55
+ cache-from: type=gha
56
+ cache-to: type=gha,mode=max
57
+
58
+
59
+ # - name: Run Docker Container from image
60
+ # # Force the repository path to lowercase using Bash parameter expansion
61
+ # # (,, is lower casing operator).
62
+ # run: |
63
+ # THIS_REPO="${{ github.repository }}"
64
+ # IMAGE_NAME="ghcr.io/${THIS_REPO,,}/test_env"
65
+ # CODE_UNDER_TEST="/tmp/fiddlesticks"
66
+
67
+ # docker run --rm \
68
+ # -v .:${CODE_UNDER_TEST} \
69
+ # ${IMAGE_NAME}:${{ steps.docker_metadata.outputs.version }} \
70
+ # sh -c ". .venv/bin/activate && pip install ${CODE_UNDER_TEST}[all] && pytest -vvx"
71
+
72
+ # # sh -c ". .venv/bin/activate && pip install ${CODE_UNDER_TEST}[all] && coverage run -m pytest -rA --tb=short ${CODE_UNDER_TEST}/tests && coverage combine && coverage report"
73
+
@@ -0,0 +1,76 @@
1
+ name: Dev tests
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ container:
12
+ image: ubuntu:26.04
13
+ options: >-
14
+ --device /dev/fuse
15
+ --cap-add SYS_ADMIN
16
+ --security-opt apparmor:unconfined
17
+ --privileged
18
+ -v /dev:/dev
19
+ steps:
20
+ - name: Check out repo
21
+ uses: actions/checkout@v7
22
+
23
+
24
+ - name: Check Git hasn't corrupted test data files
25
+ run: |
26
+ sha256sum tests/data_files/Test_vault_Do_Not_Use.kdbx
27
+
28
+ - name: Install deps
29
+ run: |
30
+ apt-get update
31
+ apt-get install -y sudo wget git 7zip python3-venv python3-pip python-is-python3
32
+
33
+
34
+ # - name: Direct Install libfuse3-4
35
+ # run: |
36
+ # sudo apt-get update && sudo apt-get install -y wget
37
+ # wget http://archive.ubuntu.com/ubuntu/pool/main/f/fuse3/libfuse3-4_3.18.2-1_amd64.deb
38
+ # sudo dpkg -i libfuse3-4_3.18.2-1_amd64.deb || sudo apt-get install -f -y
39
+
40
+ # - name: Download Veracrypt .deb
41
+ # run: wget https://github.com/veracrypt/VeraCrypt/releases/download/VeraCrypt_1.26.29/veracrypt-console-1.26.29-Ubuntu-26.04-amd64.deb
42
+
43
+ # - name: Install Veracrypt from downloaded .deb
44
+ # run: |
45
+ # sudo apt update
46
+ # sudo apt install -y software-properties-common
47
+ # sudo add-apt-repository universe
48
+ # sudo apt-get update
49
+ # # Suggests fuse3
50
+ # sudo apt-get install -y fuse3 libfuse3-dev
51
+ # sudo apt-get install -y ./veracrypt-console-1.26.29-Ubuntu-26.04-amd64.deb
52
+
53
+
54
+
55
+ - name: Create venv
56
+ run: |
57
+ python3 -m venv .venv
58
+
59
+ - name: Install dependencies
60
+ run: |
61
+ . ./.venv/bin/activate
62
+ pip install -e .[all]
63
+
64
+ - name: Run Multicore smoke test
65
+ run: |
66
+ . ./.venv/bin/activate
67
+ python dev/sketch_multicore.py
68
+
69
+
70
+
71
+ # - name: Run PW candidate Generator regression tests (to check refactor)
72
+ # run: |
73
+ # . ./.venv/bin/activate
74
+ # pytest dev/pw_generator_regression_tests.py
75
+
76
+
@@ -0,0 +1,38 @@
1
+ name: Run the tests
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ pull_request:
7
+
8
+
9
+
10
+ jobs:
11
+ tests:
12
+ runs-on: ubuntu-26.04
13
+ container:
14
+ image: ghcr.io/hazardous-area/fiddlesticks/test_env:sha-f1100e7
15
+ # Extra options needed for Veracrypt to
16
+ # mount volumes inside a Docker container
17
+ options: >-
18
+ --device /dev/fuse
19
+ --cap-add SYS_ADMIN
20
+ --security-opt apparmor:unconfined
21
+ --privileged
22
+ -v /dev:/dev
23
+ steps:
24
+ - name: Check out repo
25
+ uses: actions/checkout@v7
26
+
27
+ - name: Install code under test
28
+ run: |
29
+ . /fiddlesticks/.venv/bin/activate
30
+ pip install -e .[all]
31
+
32
+
33
+ - name: Run PyTest (via Coverage)
34
+ run: |
35
+ . /fiddlesticks/.venv/bin/activate
36
+ coverage run -m pytest -rA --tb=short tests && coverage combine && coverage report
37
+
38
+
@@ -15,3 +15,6 @@ wheels/
15
15
  # Dev environment lock file
16
16
  # (to avoid confusion with possible application lock files)
17
17
  uv.lock
18
+
19
+ # Harmless temporary test artefact
20
+ ./test.json
@@ -0,0 +1,55 @@
1
+ ARG UBUNTU_TAG=26.04
2
+
3
+ FROM ubuntu:${UBUNTU_TAG}
4
+
5
+
6
+ ENV DEBIAN_FRONTEND=noninteractive
7
+
8
+ ARG INSTALL_7Z=false
9
+ ARG INSTALL_VERACRYPT=false
10
+ ARG TEST_ENV=false
11
+
12
+ RUN apt-get update && apt-get install -y \
13
+ python3-venv \
14
+ python3-pip \
15
+ python-is-python3
16
+
17
+ RUN if [ "$INSTALL_7Z" != "false" ]; then \
18
+ apt-get update && apt-get install -y 7zip; \
19
+ fi
20
+
21
+ # Git is needed to make uses: actions/checkout work inside a
22
+ # Docker container e.g. when running the tests in Github Actions.
23
+ RUN if [ "$TEST_ENV" != "false" ]; then \
24
+ apt-get update && apt-get install -y git; \
25
+ fi
26
+
27
+ RUN if [ "$INSTALL_VERACRYPT" != "false" ]; then \
28
+ apt-get update && apt-get install -y wget && \
29
+ wget http://archive.ubuntu.com/ubuntu/pool/main/f/fuse3/libfuse3-4_3.18.2-1_amd64.deb && \
30
+ dpkg -i libfuse3-4_3.18.2-1_amd64.deb || apt-get install -f -y && \
31
+ wget https://github.com/veracrypt/VeraCrypt/releases/download/VeraCrypt_1.26.29/veracrypt-console-1.26.29-Ubuntu-26.04-amd64.deb && \
32
+ apt-get install -y software-properties-common && \
33
+ add-apt-repository universe && \
34
+ apt-get update && \
35
+ apt-get install -y fuse3 libfuse3-dev && \
36
+ apt-get install -y ./veracrypt-console-1.26.29-Ubuntu-26.04-amd64.deb && \
37
+ rm *.deb; \
38
+ fi
39
+
40
+ # Mandatory steps
41
+ WORKDIR /fiddlesticks
42
+ RUN python3 -m venv .venv
43
+
44
+ RUN .venv/bin/pip install --upgrade pip
45
+ # Only pyproject.toml is needed to install test dependency group
46
+ COPY ./LICENSE .
47
+ COPY ./pyproject.toml .
48
+ COPY ./README.md .
49
+
50
+ RUN if [ "$TEST_ENV" != "false" ]; then \
51
+ .venv/bin/pip install --group=test && \
52
+ # Install all deps of code under test now
53
+ # so they are cached in this Docker layer
54
+ .venv/bin/pip install -e .[all] --only-deps; \
55
+ fi
@@ -1,24 +1,56 @@
1
+ Metadata-Version: 2.5
2
+ Name: fiddlesticks
3
+ Version: 0.6.0
4
+ Summary: Password recovery tool for encrypted files (.7z archives .kdbx files, and Aegis archives).
5
+ Project-URL: GitHub, https://github.com/Hazardous-Area/fiddlesticks
6
+ Author-email: James Parrott <james@jamesparrott.dev>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Requires-Python: >=3.13
10
+ Provides-Extra: aegis
11
+ Requires-Dist: py-avdu; extra == 'aegis'
12
+ Provides-Extra: all
13
+ Requires-Dist: bcrypt; extra == 'all'
14
+ Requires-Dist: cryptography>=47; extra == 'all'
15
+ Requires-Dist: msoffcrypto-tool; extra == 'all'
16
+ Requires-Dist: py-avdu; extra == 'all'
17
+ Requires-Dist: py7zr; extra == 'all'
18
+ Requires-Dist: pykeepass; extra == 'all'
19
+ Provides-Extra: keepassxc
20
+ Requires-Dist: pykeepass; extra == 'keepassxc'
21
+ Provides-Extra: msoffice
22
+ Requires-Dist: msoffcrypto-tool; extra == 'msoffice'
23
+ Provides-Extra: py7zr
24
+ Requires-Dist: py7zr; extra == 'py7zr'
25
+ Provides-Extra: ssh
26
+ Requires-Dist: bcrypt; extra == 'ssh'
27
+ Requires-Dist: cryptography>=47; extra == 'ssh'
28
+ Description-Content-Type: text/markdown
29
+
1
30
  # Fiddlesticks!
2
31
  *"Aaaagh! I forgot my 7zip password"* - James (more times than he cares to remember).
32
+
3
33
  ![Tests passing](https://github.com/Hazardous-Area/fiddlesticks/actions/workflows/tests.yml/badge.svg)
4
34
  ![Code qual](https://github.com/Hazardous-Area/fiddlesticks/actions/workflows/lint.yml/badge.svg)
5
35
 
6
- Version 0.3.0
36
+ Version 0.5.0.dev
7
37
 
8
38
  ## Description
9
39
  Password recovery tool, for password-encrypted files, using simple off-line brute
10
40
  force attacks. Password candidates are generated, using common variations
11
- of a guessed password (e.g. typos and substitutions). .7z, .kdbx and Aegis archives
12
- are directly supported, but Fiddlesticks can also call any shell command, that accepts
13
- a candidate password.
41
+ of a guessed password (e.g. typos and substitutions). SSH keys and Aegis archives,
42
+ plus .7z, .kdbx, .xlsx, and .docx files,
43
+ are directly supported as optional dependencies (Veracrypt volumes too, but they're
44
+ so secure, they require 45 CPU-core-seconds per guess). But
45
+ Fiddlesticks can also call any shell command, that accepts a candidate password,
46
+ e.g. for Veracrypt volumes (and can pipe candidates to stdout).
14
47
 
15
48
  ### Raison d'etre
16
49
  - Password-protected file owners recovering their own password themselves, as long as
17
50
  they can still recall a rough guess for their password, might only need to test
18
- every candidate password that's similar enough to the guess.
51
+ every candidate password that's similar enough to their best guess.
19
52
  - This may be a much faster and cheaper computation
20
- than the one an adversary must do, without such a guess, but in possession
21
- of a stolen password protected file[^0].
53
+ than the one an adversary must do, without such a guess.
22
54
 
23
55
  ### Warning
24
56
  Strictly speaking, Fiddlesticks is a password-protected file recovery tool. Use it to
@@ -29,7 +61,7 @@ Fiddlesticks does not print the password it finds (or any candidates) unless `-P
29
61
  (or if using `--pipe` with no pipe).
30
62
 
31
63
  ### "Back of envelope" sketch 'calculation'
32
- - Attackers targetting a truly[^0] random password, must try up to `2**N`
64
+ - Attackers targetting a truly random password[^0], must try up to `2**N`
33
65
  candidate passwords (for each bit length `N` being considered).
34
66
  - Specifically, password owners may only need to consider every candidate within some
35
67
  maximum [Weighted-Levenshtein distance](https://en.wikipedia.org/wiki/Edit_distance#Types_of_edit_distance)
@@ -44,7 +76,7 @@ archive can also do so - the password wasn't strong enough.
44
76
  (e.g. this could indicate that the starting guess was wrong).
45
77
 
46
78
  ### Design and security notes
47
- *"FAQ: Why the heck should anyone in their right mind trust this with their password?"*
79
+ *"FAQ: Why the heck would anyone in their right mind trust Fiddlesticks with their password?!"*
48
80
  - Any similar 3rd party password cracking service based on 'best guess' passwords, requires
49
81
  the user to share the guesses for their passwords with the service. Even if the password
50
82
  was not used for anything else, sharing even guesses for secret credentials with 3rd parties,
@@ -85,7 +117,7 @@ Full disclaimer: Fiddlesticks does actually contain 8 lines of Bash in a string
85
117
  literal (to avoid the overhead of `subprocess.run` for every single candidate to be
86
118
  tested, and to demonstrate how any command line program could read
87
119
  password candidates from stdin). Otherwise we hope the answers to all the other questions
88
- with regards to Fiddlesticks, are all reassuring.
120
+ with regards to Fiddlesticks, are reassuring.
89
121
 
90
122
  ### Usage
91
123
  ```
@@ -130,7 +162,7 @@ the number of substitutions required for each candidate can be capped by setting
130
162
  If a file is specified in `--output-file` or `-o` Fiddlesticks will write a successfully found
131
163
  password to it. Unless `-P` or `--print-passwords` is set, Fiddlesticks does not print any
132
164
  candidate passwords by default (on successfully finding a password, the
133
- candidate number is printed; candidate generation is deterministic).
165
+ candidate index is printed; candidate generation is deterministic).
134
166
  The number of output messages (printed to stderr) can be increased by raising
135
167
  the verbosity, by setting `-v` or `--verbosity`, once or twice (e.g. `-vv`).
136
168
  "Two" is the maximum verbosity available.
@@ -160,4 +192,30 @@ limiting the substitutions to specific characters in a password guess.
160
192
  - https://en.wikipedia.org/wiki/Dictionary_attack#Dictionary_attack_software
161
193
 
162
194
  [^0] Truly random passwords are difficult for humans to remember (without writing them down or saving them).
163
- At the very least, real world adversaries (posessing a stolen file or password hash) are likely to first attempt a [dictionary attack](https://en.wikipedia.org/wiki/Dictionary_attack#Dictionary_attack_software)
195
+ At the very least, real world adversaries (posessing a stolen file or password hash) are likely to first attempt a [dictionary attack](https://en.wikipedia.org/wiki/Dictionary_attack#Dictionary_attack_software)
196
+
197
+ ## Benchmarks
198
+ - Github Actions Ubuntu runner (4 core)
199
+
200
+ | Num subs |Num pwds | .xlsx/s | per pwd/ms | .kdbx/s | per pwd/ms | .json/s | per pwd/ms | .7z /s | per pwd/ms | .key /s | per pwd/ms | .hc /s | per pwd/ms |
201
+ |----------|:-------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|
202
+ | 0 | 1 | 0| 1.0| 0| 0.0| 0| 1.0| 0| 0.0| 0| 164.0| 0| 1.0|
203
+ | 1 | 42 | 0| 11.0| 0| 5.0| 0| 6.0| 0| 0.0| 0| 6.0| 0| 8.0|
204
+ | 2 | 842 | 3| 3.0| 1| 2.0| 2| 2.0| 2| 2.0| 2| 3.0| 1| 2.0|
205
+ | 3 | 10724 | 38| 3.0| 22| 2.0| 28| 2.0| 29| 2.0| 27| 2.0| 28| 2.0|
206
+ | 4 | 97431 | 281| 2.0| 254| 2.0| 233| 2.0| 212| 2.0| 254| 2.0| 240| 2.0|
207
+ | 5 | 672118 | 1883| 2.0| 1967| 2.0| 1636| 2.0| 1701| 2.0| 1382| 2.0| 1497| 2.0|
208
+
209
+
210
+
211
+ - Hetzner CX23 x86 4GB
212
+ - fiddlesticks v0.5.0.dev
213
+ - guess=[`correcthorsebatterystaple`](https://xkcd.com/936/)
214
+
215
+ | Num subs |Num pwds | .xlsx/s | per pwd/ms | .kdbx/s | per pwd/ms | .json/s | per pwd/ms | .7z /s | per pwd/ms | .key /s | per pwd/ms | .hc /s | per pwd/ms |
216
+ |----------|:-------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|
217
+ | 0 | 1 | 0| 71.0| 0| 110.0| 0| 148.0| 0| 221.0| 0| 261.0| 45| 45610.0|
218
+ | 1 | 42 | 2| 59.0| 3| 90.0| 6| 147.0| 9| 230.0| 10| 257.0| | |
219
+ | 2 | 842 | 46| 55.0| 76| 90.0| 121| 144.0| 186| 221.0| 216| 257.0| | |
220
+ | 3 | 10724 | 573| 53.0| 991| 92.0| | | | | | | | |
221
+
@@ -1,41 +1,27 @@
1
- Metadata-Version: 2.5
2
- Name: fiddlesticks
3
- Version: 0.3.0
4
- Summary: Password recovery tool for encrypted files (.7z archives .kdbx files, and Aegis archives).
5
- Project-URL: GitHub, https://github.com/Hazardous-Area/fiddlesticks
6
- Author-email: James Parrott <james@jamesparrott.dev>
7
- License-Expression: MIT
8
- License-File: LICENSE
9
- Requires-Python: >=3.12
10
- Provides-Extra: aegis
11
- Requires-Dist: py-avdu; extra == 'aegis'
12
- Provides-Extra: keepassxc
13
- Requires-Dist: pykeepass; extra == 'keepassxc'
14
- Provides-Extra: py7zr
15
- Requires-Dist: py7zr; extra == 'py7zr'
16
- Description-Content-Type: text/markdown
17
-
18
1
  # Fiddlesticks!
19
2
  *"Aaaagh! I forgot my 7zip password"* - James (more times than he cares to remember).
3
+
20
4
  ![Tests passing](https://github.com/Hazardous-Area/fiddlesticks/actions/workflows/tests.yml/badge.svg)
21
5
  ![Code qual](https://github.com/Hazardous-Area/fiddlesticks/actions/workflows/lint.yml/badge.svg)
22
6
 
23
- Version 0.3.0
7
+ Version 0.5.0.dev
24
8
 
25
9
  ## Description
26
10
  Password recovery tool, for password-encrypted files, using simple off-line brute
27
11
  force attacks. Password candidates are generated, using common variations
28
- of a guessed password (e.g. typos and substitutions). .7z, .kdbx and Aegis archives
29
- are directly supported, but Fiddlesticks can also call any shell command, that accepts
30
- a candidate password.
12
+ of a guessed password (e.g. typos and substitutions). SSH keys and Aegis archives,
13
+ plus .7z, .kdbx, .xlsx, and .docx files,
14
+ are directly supported as optional dependencies (Veracrypt volumes too, but they're
15
+ so secure, they require 45 CPU-core-seconds per guess). But
16
+ Fiddlesticks can also call any shell command, that accepts a candidate password,
17
+ e.g. for Veracrypt volumes (and can pipe candidates to stdout).
31
18
 
32
19
  ### Raison d'etre
33
20
  - Password-protected file owners recovering their own password themselves, as long as
34
21
  they can still recall a rough guess for their password, might only need to test
35
- every candidate password that's similar enough to the guess.
22
+ every candidate password that's similar enough to their best guess.
36
23
  - This may be a much faster and cheaper computation
37
- than the one an adversary must do, without such a guess, but in possession
38
- of a stolen password protected file[^0].
24
+ than the one an adversary must do, without such a guess.
39
25
 
40
26
  ### Warning
41
27
  Strictly speaking, Fiddlesticks is a password-protected file recovery tool. Use it to
@@ -46,7 +32,7 @@ Fiddlesticks does not print the password it finds (or any candidates) unless `-P
46
32
  (or if using `--pipe` with no pipe).
47
33
 
48
34
  ### "Back of envelope" sketch 'calculation'
49
- - Attackers targetting a truly[^0] random password, must try up to `2**N`
35
+ - Attackers targetting a truly random password[^0], must try up to `2**N`
50
36
  candidate passwords (for each bit length `N` being considered).
51
37
  - Specifically, password owners may only need to consider every candidate within some
52
38
  maximum [Weighted-Levenshtein distance](https://en.wikipedia.org/wiki/Edit_distance#Types_of_edit_distance)
@@ -61,7 +47,7 @@ archive can also do so - the password wasn't strong enough.
61
47
  (e.g. this could indicate that the starting guess was wrong).
62
48
 
63
49
  ### Design and security notes
64
- *"FAQ: Why the heck should anyone in their right mind trust this with their password?"*
50
+ *"FAQ: Why the heck would anyone in their right mind trust Fiddlesticks with their password?!"*
65
51
  - Any similar 3rd party password cracking service based on 'best guess' passwords, requires
66
52
  the user to share the guesses for their passwords with the service. Even if the password
67
53
  was not used for anything else, sharing even guesses for secret credentials with 3rd parties,
@@ -102,7 +88,7 @@ Full disclaimer: Fiddlesticks does actually contain 8 lines of Bash in a string
102
88
  literal (to avoid the overhead of `subprocess.run` for every single candidate to be
103
89
  tested, and to demonstrate how any command line program could read
104
90
  password candidates from stdin). Otherwise we hope the answers to all the other questions
105
- with regards to Fiddlesticks, are all reassuring.
91
+ with regards to Fiddlesticks, are reassuring.
106
92
 
107
93
  ### Usage
108
94
  ```
@@ -147,7 +133,7 @@ the number of substitutions required for each candidate can be capped by setting
147
133
  If a file is specified in `--output-file` or `-o` Fiddlesticks will write a successfully found
148
134
  password to it. Unless `-P` or `--print-passwords` is set, Fiddlesticks does not print any
149
135
  candidate passwords by default (on successfully finding a password, the
150
- candidate number is printed; candidate generation is deterministic).
136
+ candidate index is printed; candidate generation is deterministic).
151
137
  The number of output messages (printed to stderr) can be increased by raising
152
138
  the verbosity, by setting `-v` or `--verbosity`, once or twice (e.g. `-vv`).
153
139
  "Two" is the maximum verbosity available.
@@ -177,4 +163,30 @@ limiting the substitutions to specific characters in a password guess.
177
163
  - https://en.wikipedia.org/wiki/Dictionary_attack#Dictionary_attack_software
178
164
 
179
165
  [^0] Truly random passwords are difficult for humans to remember (without writing them down or saving them).
180
- At the very least, real world adversaries (posessing a stolen file or password hash) are likely to first attempt a [dictionary attack](https://en.wikipedia.org/wiki/Dictionary_attack#Dictionary_attack_software)
166
+ At the very least, real world adversaries (posessing a stolen file or password hash) are likely to first attempt a [dictionary attack](https://en.wikipedia.org/wiki/Dictionary_attack#Dictionary_attack_software)
167
+
168
+ ## Benchmarks
169
+ - Github Actions Ubuntu runner (4 core)
170
+
171
+ | Num subs |Num pwds | .xlsx/s | per pwd/ms | .kdbx/s | per pwd/ms | .json/s | per pwd/ms | .7z /s | per pwd/ms | .key /s | per pwd/ms | .hc /s | per pwd/ms |
172
+ |----------|:-------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|
173
+ | 0 | 1 | 0| 1.0| 0| 0.0| 0| 1.0| 0| 0.0| 0| 164.0| 0| 1.0|
174
+ | 1 | 42 | 0| 11.0| 0| 5.0| 0| 6.0| 0| 0.0| 0| 6.0| 0| 8.0|
175
+ | 2 | 842 | 3| 3.0| 1| 2.0| 2| 2.0| 2| 2.0| 2| 3.0| 1| 2.0|
176
+ | 3 | 10724 | 38| 3.0| 22| 2.0| 28| 2.0| 29| 2.0| 27| 2.0| 28| 2.0|
177
+ | 4 | 97431 | 281| 2.0| 254| 2.0| 233| 2.0| 212| 2.0| 254| 2.0| 240| 2.0|
178
+ | 5 | 672118 | 1883| 2.0| 1967| 2.0| 1636| 2.0| 1701| 2.0| 1382| 2.0| 1497| 2.0|
179
+
180
+
181
+
182
+ - Hetzner CX23 x86 4GB
183
+ - fiddlesticks v0.5.0.dev
184
+ - guess=[`correcthorsebatterystaple`](https://xkcd.com/936/)
185
+
186
+ | Num subs |Num pwds | .xlsx/s | per pwd/ms | .kdbx/s | per pwd/ms | .json/s | per pwd/ms | .7z /s | per pwd/ms | .key /s | per pwd/ms | .hc /s | per pwd/ms |
187
+ |----------|:-------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|:-------:|:----------:|
188
+ | 0 | 1 | 0| 71.0| 0| 110.0| 0| 148.0| 0| 221.0| 0| 261.0| 45| 45610.0|
189
+ | 1 | 42 | 2| 59.0| 3| 90.0| 6| 147.0| 9| 230.0| 10| 257.0| | |
190
+ | 2 | 842 | 46| 55.0| 76| 90.0| 121| 144.0| 186| 221.0| 216| 257.0| | |
191
+ | 3 | 10724 | 573| 53.0| 991| 92.0| | | | | | | | |
192
+