# pdf2john
A Rust tool that extracts password hashes from encrypted PDF files for use with [John the Ripper](https://www.openwall.com/john/).
This is a rewrite of the Python [pdf2john](https://github.com/openwall/john/blob/bleeding-jumbo/run/pdf2john.py) script, producing identical output.
## Install
```
cargo install pdf2john
```
## Build
```
cargo build --release
```
## Usage
```
pdf2john [OPTIONS] <PDF_FILES>...
```
### Arguments
- `<PDF_FILES>...` - One or more PDF files to extract hashes from
### Options
- `-s`, `--show-filename` - Prefix output with `filename:` (John the Ripper convention)
- `-h`, `--help` - Print help
### Examples
Extract a hash:
```
$ pdf2john encrypted.pdf
$pdf$2*3*128*-1852*1*16*8c9f0eed2812e81a...
```
Extract with filename prefix (for use with John):
```
$ pdf2john -s encrypted.pdf
encrypted.pdf:$pdf$2*3*128*-1852*1*16*8c9f0eed2812e81a...
```
Process multiple files:
```
$ pdf2john file1.pdf file2.pdf file3.pdf
```
Pipe directly to John the Ripper:
```
$ pdf2john encrypted.pdf > hash.txt
$ john hash.txt
```
## Output Format
```
$pdf$<V>*<R>*<Length>*<P>*<EncryptMetadata>*<id_len>*<id_hex>*<u_len>*<u_hex>*<o_len>*<o_hex>
```
For revision 5/6 PDFs, additional fields are appended:
```
...*<oe_len>*<oe_hex>*<ue_len>*<ue_hex>
```
## Supported Encryption Revisions
| 2 | RC4 (basic) | 32 bytes |
| 3 | RC4 (extended) | 32 bytes |
| 4 | RC4 or AES-128 | 32 bytes |
| 5 | AES-256 (R5) | 48 bytes |
| 6 | AES-256 | 48 bytes |
## Testing
```
cargo test
```
Test PDFs and expected hashes are in `docs/`. The expected hashes were generated by [pdf2john.py](https://github.com/openwall/john/blob/bleeding-jumbo/run/pdf2john.py) and are used to verify identical output. The test suite covers:
| `r2_rc4_40.pdf` | RC4, 40-bit (R2) |
| `r3_rc4_128.pdf` | RC4, 128-bit (R3) |
| `r4_aes_128.pdf` | AES-128 (R4) |
| `r6_aes_256.pdf` | AES-256 (R6) |
## License
See [LICENSE](LICENSE). Redistribution and use in source and binary forms, with or without modification, are permitted.