# Pyrit, the pre-computed WPA key database that outlived Python 2

> Classic Pyrit builds a database of pre-computed WPA/WPA2 Pairwise Master Keys and trades storage for time, using CPUs, CUDA and OpenCL together across a network. The tree here is the original Python 2.7 code, restored to build again on current Debian, Ubuntu and Kali, and the README points new work at a separate Python 3 rewrite.

**JPaulMora/Pyrit** — The famous WPA precomputed cracker, Migrated from Google.

- Repository: https://github.com/JPaulMora/Pyrit
- Stars: 1,138 · Forks: 272
- Language: Python
- License: GPL-3.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/jpaulmora-pyrit

## A space-time tradeoff, and why the tradeoff is worth it

Pyrit allows you to create massive databases of pre-computed WPA/WPA2-PSK authentication phase material in a space-time tradeoff, and the README explains the mechanism in a way that is worth reading carefully because it is the whole design.

The reason the protocol is attackable is the shared master key. WPA/WPA2-PSK is a subset of IEEE 802.11 WPA/WPA2 that skips the complex task of key distribution and client authentication by assigning every participating party the same pre-shared key. That master key is derived from a password the administrator pre-configures. When a client connects, a new session key is derived from the master key to encrypt and authenticate the traffic.

Using a single master key instead of per-user keys eases deployment for home and small office networks, and the cost of that convenience is that the protocol is vulnerable to brute force against its key negotiation phase. The README calls the vulnerability exceptionally disastrous, because the protocol allows much of the key derivation to be pre-computed, which makes simple brute force attacks even more alluring to the attacker.

The technical framing is that every Pairwise Master Key is worth exactly one megabyte of data pushed through PBKDF2-HMAC-SHA1. In turn, computing 10,000 PMKs per second is equivalent to hashing 9.8 gigabyte of data with SHA1 in one second. That is the number that makes the tradeoff concrete. You are not cracking the password directly, you are pre-computing the expensive part once and then comparing.

The computational work is distributed across multi-core CPUs and other platforms through ATI Stream, Nvidia CUDA and OpenCL, and the README describes three topologies for how multiple nodes reach one storage server: a single storage such as a MySQL server, a local network where four computational nodes exist and only one actually touches the storage server, and an untrusted network where three nodes exist and two reach the storage through Pyrit's RPC interface.

## The tree you are looking at is deliberately the old one

The first thing the README does is redirect you. It says Pyrit3 is out, a from-scratch Python 3 rewrite, and to use that for new work. What this repository holds is classic Pyrit, and the README is explicit that it is still Python 2.7, but that it has been updated so it builds and runs again on current Debian, Ubuntu and Kali using pyenv and distro CUDA packages.

That distinction is not cosmetic, because Python 2.7 reached its end of life long ago and current Debian, Ubuntu and Kali images no longer ship it. So this tree cannot simply be cloned and installed with apt. The What's new section lists what the restoration covered: the tree was restored so it works again on Python 2.7 and the incomplete Python 3 conversion is not used, install docs for recent Debian, Ubuntu and Kali were added via pyenv and distro CUDA packages, issues 479 and 481 were fixed, Pyrit CUDA now compiles on OSX with Toolkit 7.5, use_CUDA and use_OpenCL were added in the config file, core listing and management was improved, limit_ncpus now disables all CPUs when set to a value of 0 or less, and CCMP packet identification was improved.

The release history reflects the split. The single tag is v0.5.0 from 2015-10-01, while setup.py carries a VERSION constant of 0.5.1, which suggests the tree moved on after the last tag was cut. The last push was on 2026-08-31, so the repository is being worked on, but the released artefact is from 2015.

The licence is GPL-3.0-or-later, and the README makes a point of the reason: Pyrit is free software, free as in freedom, and everyone can inspect, copy or modify it and share derived work under the GNU General Public License v3+. The open development and the copyleft licensing are presented as the answer to the question of what stops this from being a black box for misuse, and the same section says the author does not encourage or support using Pyrit for the infringement of people's communication privacy, framing the exploration of the technology as its own purpose.

## Building it on a current distribution, step by step

The installation section is unusually practical, and it opens with a warning that the old notes will not work. It says that on recent Debian, Ubuntu and Kali images you must install Python 2.7 with pyenv and the distro CUDA packages, and that older notes using python2-dev, sudo pip, apt-get install pyrit or the Kali 2018 NVIDIA DKMS steps will not work on a recent install.

The first step is a system update, and a reboot if the kernel moved:

```bash
sudo apt update
sudo apt upgrade -y
```

Then the optional GPU path, which you skip if you only want the CPU core:

```bash
lspci | grep -i vga
sudo apt install -y nvidia-driver nvidia-cuda-toolkit
sudo reboot
```

After the reboot, nvcc --version should work, and the README notes that hashcat -b is a useful extra check that the GPU stack is alive.

The build headers for pyenv and Pyrit are then installed:

```bash
sudo apt install -y \
  build-essential curl git \
  libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \
  libpcap-dev
```

And the README flags the naming trap directly, since zlib-devel and openssl-dev are the Fedora names while on Debian the packages are zlib1g-dev and libssl-dev. The libpcap-dev package is there for the packet capture side of the tool.

Python 2.7.18 comes from pyenv, which is installed with the curl bootstrap and then configured in your shell:

```bash
curl https://pyenv.run | bash
```

```bash
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
```

```bash
pyenv install 2.7.18
```

Finally the clone, the version pin and the build:

```bash
git clone https://github.com/JPaulMora/Pyrit.git
cd Pyrit
pyenv local 2.7.18
pip install 'scapy==2.4.5' 'sqlalchemy<2'
python setup.py clean
python setup.py build
python setup.py install
```

Two warnings come with that. Do not prefix those python and pip commands with sudo, because that would ignore pyenv and hit the system interpreter. And leave the source tree before running pyrit, so that Python does not pick up the local cpyrit package instead of the installed one. The cpyrit/ directory in the repository is that local package, so the cd out is not a formality.

The dependency notes follow: scapy is required for analyze and attack, sqlalchemy is optional unless you use SQL storage, and PostgreSQL additionally needs psycopg2==2.8.6.

## The C extension that guesses whether your CPU has AES-NI

Pyrit is a Python program with a compiled core, and the setup.py shows how that core is built.

The file carries the original copyright of John Mora and the original work by Lukas Lueg, and it is licensed under the GNU General Public License as the header explains. The build uses distutils rather than setuptools, and the interesting part is the custom build_ext subclass.

The extension sources include .S files, since UnixCCompiler.src_extensions.append('.S') adds assembly to the list the compiler will pick up, and the extra compile arguments are -Wall, -fno-strict-aliasing and a VERSION define.

Then there is the CPU feature detection. The comment says support for AES-NI intrinsics is not found everywhere, so on darwin and linux2 platforms with an x86_64 or i386 machine the flags -maes and -mpclmul are added. The LazyBuilder class then tries to build the cpyrit_cpu extension with -maes and -mpclmul first, and if that fails simply retries with those flags disabled. The class docstring is candid about it: this is not exactly elegant but it is probably the most portable solution given the limited capabilities of distutils to detect compiler versions.

That is a piece of engineering from a different era, and it is worth reading as a lesson rather than as a recommendation. The assumption is that the build might be attempted on hardware without AES-NI, and the fallback is to try the accelerated path and back off rather than to check a CPUID bit up front. The result is that the same source builds on old and new processors, at the cost of a build step that can fail and retry.

The repository layout is consistent with a Python 2 era project. There is a cpyrit/ directory for the compiled core, modules/ for the optional pieces, a pyrit directory and pyrit_cli.py for the command line entry points, test/ for the tests, a setup.py, a MANIFEST.in, a COPYING file for the licence, a CHANGELOG, and a .python-version file.

## Using it, and the boundaries of the exercise

The README points at two things beyond the code: a Tutorial on the project wiki and a reference manual for the command line client. The last section of the installation notes shows the shape of a session, and it is short. After the build you leave the source directory and run the pyrit command.

What Pyrit does with a network is the part that needs care. The project is a security research tool, and the pattern of use the README describes is a space-time tradeoff, which means the tool is built for people who have time and storage and want to test a password against a pre-computed table.

That is a legitimate activity on a network you are authorised to test, and the same page makes the boundaries explicit. The README states that the author does not encourage or support using Pyrit for the infringement of people's communication privacy, and it explains that the exploration and realization of the technology is documented by the open development, the strictly source-code-based distribution and the copyleft licensing.

The technical constraint that makes this sensible is the hash construction. Because a PMK is derived through PBKDF2-HMAC-SHA1, and because the pre-computation is a table of derived values, the tool is comparing derived keys rather than reading a password off the wire. It still needs the four-way handshake material to do that, which is why a packet capture library is a dependency, and it still needs the target to be reachable, which is why a capture interface appears in the install steps.

The honest reading of the project is that it is an unusually well-documented piece of security research that outlived its ecosystem. The code is here because the study of that vulnerability is worth doing in the open, and the current tree exists because the original author wanted it to keep working on the machines people actually have.

## Conclusion

Pyrit suits a security researcher or penetration tester working on a wireless network they are authorised to test, since the pre-computation database changes what a weak password attempt costs, and it suits someone who wants the original Pyrit protocol work rather than a modern rewrite. It is the wrong choice for new work, because the README itself directs you to Pyrit3, the from-scratch Python 3 rewrite, and it is the wrong choice if you want a quick tool, since this tree needs Python 2.7 installed through pyenv on a current distribution. Before building it, note that Windows is not supported, that the whole project is licensed GPL-3.0-or-later, and that Pyrit's own README states the author does not support using it for the infringement of people's communication privacy.

## FAQ

### Is Pyrit still maintained, and should I use this repository?

The README says Pyrit3 is out as a from-scratch Python 3 rewrite and to use that for new work. This repository is classic Pyrit, still Python 2.7, and was updated so it builds and runs again on current Debian, Ubuntu and Kali via pyenv and distro CUDA packages.

### How do I install Pyrit on a current Ubuntu or Kali system?

Install the build headers including libpcap-dev, install Python 2.7.18 with pyenv, then clone the repository, set pyenv local 2.7.18, install scapy==2.4.5 and sqlalchemy<2, and run setup.py clean, build and install. Do not use sudo for the python and pip commands, or pyenv is bypassed.

### What does Pyrit need from a GPU?

The GPU path is optional. Installing the nvidia-driver and nvidia-cuda-toolkit packages and rebooting makes nvcc --version work, and hashcat -b is a useful extra check that the GPU stack is alive. The README says to skip this step if you only want the CPU core.

### How does Pyrit use a storage server and multiple nodes?

The README describes three topologies: a single storage such as a MySQL server, a local network with four computational nodes where only one accesses the storage server directly, and an untrusted network with three nodes where two access the storage through Pyrit's RPC interface.

### What licence is Pyrit released under?

The project is licensed under the GNU General Public License v3 or later, and the README frames that as part of the point, since open development, source-code-based distribution and copyleft licensing are how the author documents the limits of the project.

## Sources

- [Issues](https://github.com/JPaulMora/Pyrit/issues)
- [JPaulMora/Pyrit on GitHub](https://github.com/JPaulMora/Pyrit)
- [License: GPL-3.0](https://github.com/JPaulMora/Pyrit/blob/master/LICENSE)
- [README](https://github.com/JPaulMora/Pyrit/blob/master/README.md)
- [Releases](https://github.com/JPaulMora/Pyrit/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jpaulmora-pyrit
