fiddlesticks 0.4.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 (34) hide show
  1. fiddlesticks-0.6.0/.github/workflows/benchmarks.yml +72 -0
  2. fiddlesticks-0.6.0/.github/workflows/build_test_env.yml +73 -0
  3. fiddlesticks-0.6.0/.github/workflows/dev_tests.yml +76 -0
  4. fiddlesticks-0.6.0/.github/workflows/tests.yml +38 -0
  5. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/.gitignore +3 -0
  6. fiddlesticks-0.6.0/Dockerfile +55 -0
  7. fiddlesticks-0.4.0/README.md → fiddlesticks-0.6.0/PKG-INFO +68 -12
  8. fiddlesticks-0.4.0/PKG-INFO → fiddlesticks-0.6.0/README.md +39 -34
  9. fiddlesticks-0.6.0/benchmarks.py +215 -0
  10. fiddlesticks-0.6.0/dev/Candidate_iteration_11.6h_estimate.ods +0 -0
  11. fiddlesticks-0.6.0/dev/pw_generator_regression_tests.py +142 -0
  12. fiddlesticks-0.6.0/dev/sketch_multicore.py +162 -0
  13. fiddlesticks-0.6.0/fiddlesticks_benchmarks.txt +7 -0
  14. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/pyproject.toml +16 -3
  15. fiddlesticks-0.6.0/src/fiddlesticks.py +1444 -0
  16. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/tests/checker_tests.py +79 -17
  17. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/tests/end_to_end_tests.py +142 -30
  18. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/tests/helpers.py +61 -2
  19. fiddlesticks-0.6.0/tests/misc_tests.py +291 -0
  20. fiddlesticks-0.6.0/tests/pw_generator_tests.py +264 -0
  21. fiddlesticks-0.4.0/.github/workflows/tests.yml +0 -44
  22. fiddlesticks-0.4.0/src/fiddlesticks.py +0 -894
  23. fiddlesticks-0.4.0/tests/misc_tests.py +0 -121
  24. fiddlesticks-0.4.0/tests/pw_generator_tests.py +0 -55
  25. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/.gitattributes +0 -0
  26. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/.github/workflows/lint.yml +0 -0
  27. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/.pre-commit-config.yaml +0 -0
  28. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/CANARY +0 -0
  29. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/LICENSE +0 -0
  30. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/tests/__init__.py +0 -0
  31. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/tests/data_files/Test_vault_Do_Not_Use.kdbx +0 -0
  32. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/tests/data_files/foo.7z +0 -0
  33. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/tests/data_files/test.docx +0 -0
  34. {fiddlesticks-0.4.0 → fiddlesticks-0.6.0}/tests/data_files/test.xlsx +0 -0
@@ -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,26 +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.4.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). SSH keys, Aegis archives,
12
- and Veracrypt volumes, plus .7z, .kdbx, .xlsx, and .docx files,
13
- are directly supported as optional dependencies. But
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
14
45
  Fiddlesticks can also call any shell command, that accepts a candidate password,
15
46
  e.g. for Veracrypt volumes (and can pipe candidates to stdout).
16
47
 
17
48
  ### Raison d'etre
18
49
  - Password-protected file owners recovering their own password themselves, as long as
19
50
  they can still recall a rough guess for their password, might only need to test
20
- every candidate password that's similar enough to the guess.
51
+ every candidate password that's similar enough to their best guess.
21
52
  - This may be a much faster and cheaper computation
22
- than the one an adversary must do, without such a guess, but in possession
23
- of a stolen password protected file[^0].
53
+ than the one an adversary must do, without such a guess.
24
54
 
25
55
  ### Warning
26
56
  Strictly speaking, Fiddlesticks is a password-protected file recovery tool. Use it to
@@ -31,7 +61,7 @@ Fiddlesticks does not print the password it finds (or any candidates) unless `-P
31
61
  (or if using `--pipe` with no pipe).
32
62
 
33
63
  ### "Back of envelope" sketch 'calculation'
34
- - 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`
35
65
  candidate passwords (for each bit length `N` being considered).
36
66
  - Specifically, password owners may only need to consider every candidate within some
37
67
  maximum [Weighted-Levenshtein distance](https://en.wikipedia.org/wiki/Edit_distance#Types_of_edit_distance)
@@ -46,7 +76,7 @@ archive can also do so - the password wasn't strong enough.
46
76
  (e.g. this could indicate that the starting guess was wrong).
47
77
 
48
78
  ### Design and security notes
49
- *"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?!"*
50
80
  - Any similar 3rd party password cracking service based on 'best guess' passwords, requires
51
81
  the user to share the guesses for their passwords with the service. Even if the password
52
82
  was not used for anything else, sharing even guesses for secret credentials with 3rd parties,
@@ -87,7 +117,7 @@ Full disclaimer: Fiddlesticks does actually contain 8 lines of Bash in a string
87
117
  literal (to avoid the overhead of `subprocess.run` for every single candidate to be
88
118
  tested, and to demonstrate how any command line program could read
89
119
  password candidates from stdin). Otherwise we hope the answers to all the other questions
90
- with regards to Fiddlesticks, are all reassuring.
120
+ with regards to Fiddlesticks, are reassuring.
91
121
 
92
122
  ### Usage
93
123
  ```
@@ -132,7 +162,7 @@ the number of substitutions required for each candidate can be capped by setting
132
162
  If a file is specified in `--output-file` or `-o` Fiddlesticks will write a successfully found
133
163
  password to it. Unless `-P` or `--print-passwords` is set, Fiddlesticks does not print any
134
164
  candidate passwords by default (on successfully finding a password, the
135
- candidate number is printed; candidate generation is deterministic).
165
+ candidate index is printed; candidate generation is deterministic).
136
166
  The number of output messages (printed to stderr) can be increased by raising
137
167
  the verbosity, by setting `-v` or `--verbosity`, once or twice (e.g. `-vv`).
138
168
  "Two" is the maximum verbosity available.
@@ -162,4 +192,30 @@ limiting the substitutions to specific characters in a password guess.
162
192
  - https://en.wikipedia.org/wiki/Dictionary_attack#Dictionary_attack_software
163
193
 
164
194
  [^0] Truly random passwords are difficult for humans to remember (without writing them down or saving them).
165
- 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,48 +1,27 @@
1
- Metadata-Version: 2.5
2
- Name: fiddlesticks
3
- Version: 0.4.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: msoffice
15
- Requires-Dist: msoffcrypto-tool; extra == 'msoffice'
16
- Provides-Extra: py7zr
17
- Requires-Dist: py7zr; extra == 'py7zr'
18
- Provides-Extra: ssh
19
- Requires-Dist: bcrypt; extra == 'ssh'
20
- Requires-Dist: cryptography>=47; extra == 'ssh'
21
- Description-Content-Type: text/markdown
22
-
23
1
  # Fiddlesticks!
24
2
  *"Aaaagh! I forgot my 7zip password"* - James (more times than he cares to remember).
3
+
25
4
  ![Tests passing](https://github.com/Hazardous-Area/fiddlesticks/actions/workflows/tests.yml/badge.svg)
26
5
  ![Code qual](https://github.com/Hazardous-Area/fiddlesticks/actions/workflows/lint.yml/badge.svg)
27
6
 
28
- Version 0.4.0
7
+ Version 0.5.0.dev
29
8
 
30
9
  ## Description
31
10
  Password recovery tool, for password-encrypted files, using simple off-line brute
32
11
  force attacks. Password candidates are generated, using common variations
33
- of a guessed password (e.g. typos and substitutions). SSH keys, Aegis archives,
34
- and Veracrypt volumes, plus .7z, .kdbx, .xlsx, and .docx files,
35
- are directly supported as optional dependencies. But
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
36
16
  Fiddlesticks can also call any shell command, that accepts a candidate password,
37
17
  e.g. for Veracrypt volumes (and can pipe candidates to stdout).
38
18
 
39
19
  ### Raison d'etre
40
20
  - Password-protected file owners recovering their own password themselves, as long as
41
21
  they can still recall a rough guess for their password, might only need to test
42
- every candidate password that's similar enough to the guess.
22
+ every candidate password that's similar enough to their best guess.
43
23
  - This may be a much faster and cheaper computation
44
- than the one an adversary must do, without such a guess, but in possession
45
- of a stolen password protected file[^0].
24
+ than the one an adversary must do, without such a guess.
46
25
 
47
26
  ### Warning
48
27
  Strictly speaking, Fiddlesticks is a password-protected file recovery tool. Use it to
@@ -53,7 +32,7 @@ Fiddlesticks does not print the password it finds (or any candidates) unless `-P
53
32
  (or if using `--pipe` with no pipe).
54
33
 
55
34
  ### "Back of envelope" sketch 'calculation'
56
- - 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`
57
36
  candidate passwords (for each bit length `N` being considered).
58
37
  - Specifically, password owners may only need to consider every candidate within some
59
38
  maximum [Weighted-Levenshtein distance](https://en.wikipedia.org/wiki/Edit_distance#Types_of_edit_distance)
@@ -68,7 +47,7 @@ archive can also do so - the password wasn't strong enough.
68
47
  (e.g. this could indicate that the starting guess was wrong).
69
48
 
70
49
  ### Design and security notes
71
- *"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?!"*
72
51
  - Any similar 3rd party password cracking service based on 'best guess' passwords, requires
73
52
  the user to share the guesses for their passwords with the service. Even if the password
74
53
  was not used for anything else, sharing even guesses for secret credentials with 3rd parties,
@@ -109,7 +88,7 @@ Full disclaimer: Fiddlesticks does actually contain 8 lines of Bash in a string
109
88
  literal (to avoid the overhead of `subprocess.run` for every single candidate to be
110
89
  tested, and to demonstrate how any command line program could read
111
90
  password candidates from stdin). Otherwise we hope the answers to all the other questions
112
- with regards to Fiddlesticks, are all reassuring.
91
+ with regards to Fiddlesticks, are reassuring.
113
92
 
114
93
  ### Usage
115
94
  ```
@@ -154,7 +133,7 @@ the number of substitutions required for each candidate can be capped by setting
154
133
  If a file is specified in `--output-file` or `-o` Fiddlesticks will write a successfully found
155
134
  password to it. Unless `-P` or `--print-passwords` is set, Fiddlesticks does not print any
156
135
  candidate passwords by default (on successfully finding a password, the
157
- candidate number is printed; candidate generation is deterministic).
136
+ candidate index is printed; candidate generation is deterministic).
158
137
  The number of output messages (printed to stderr) can be increased by raising
159
138
  the verbosity, by setting `-v` or `--verbosity`, once or twice (e.g. `-vv`).
160
139
  "Two" is the maximum verbosity available.
@@ -184,4 +163,30 @@ limiting the substitutions to specific characters in a password guess.
184
163
  - https://en.wikipedia.org/wiki/Dictionary_attack#Dictionary_attack_software
185
164
 
186
165
  [^0] Truly random passwords are difficult for humans to remember (without writing them down or saving them).
187
- 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
+