PassBERT: BERT-based Password Reuse Strength Meter
PassBERT: BERT-based Password Reuse Strength Meter
This is a README file for a submodule in the RAID’26 paper VersaPSE: Versatile Password Strength Evaluation Using Continual Learning.
PassBERT models the transformation from a source password to a target password as a sequence of in-place edit operations. For a given source password, the model predicts, at every character position, an edit operation (keep / delete / substitute / double-substitute). The probability of the target password’s edit path serves as the password strength.
Note that this is a reproduced version of PassBERT, not the code provided by the original paper. The open-source implementation was built under a very old version of TensorFlow, which isn’t widely supported on recent GPU architectures.
Pipeline Overview
raw (src, trg) pairs
│
▼
editpath.py ──► in-place edit paths (src \t trg \t encoded_labels)
│
▼
bert_pretrain.py ──► MLM pretrained char-level BERT (optional, Chinese/English)
│
▼
bert_local_train.py ──► local model per dataset (from pretrained BERT)
│
▼
bert_global_train.py ──► local-to-global model (fine-tune on rockyou/tianya)
│
▼
eval.py ──► reuse-strength probabilities
File Overview
| File | Purpose |
|---|---|
config.py |
Global configuration: maximum password length (MAX_LEN = 30). |
model.py |
The PassBERT model: char-level BERT encoder + per-position linear classification head. Includes freeze_layers() and prob_extract(). |
utils.py |
Character vocabulary, password -> token-id conversion, dataset classes and collate functions for the edit-path labeling task. |
editpath.py |
Edit-distance (Levenshtein) alignment of password pairs and conversion into in-place edit operation paths. We borrowed this file from the original PassBERT implementation for consistency. |
bert_pretrain.py |
Pre-trains a char-level BERT (Masked Language Modeling) on a password corpus (Rockyou-withcount.txt). |
bert_local_train.py |
Local training: initializes BERT from a pretrained checkpoint and trains the whole network on one dataset’s edit paths. |
bert_global_train.py |
Local-to-global training: starts from a local checkpoint, freezes most layers, fine-tunes on the global corpus. |
train.py |
General-purpose training script: builds global base models, global-to-local adaptation, and no-freeze variants. |
eval.py |
Evaluation: computes the probability of each ground-truth edit path in a test file. |
Data Format
Raw password-pair files are tab-separated, one pair per line:
<source_password>\t<target_password>
- Raw (src, trg) pairs come from
../dataset/:- Training:
../dataset/train/pseudo_train_data-sister.txtand../dataset/train/pseudo_train_data-popular.txt - Test:
../dataset/test/pseudo_test_data-targeted.txtand../dataset/test/pseudo_test_data-untargeted.txt
- Training:
editpath.py converts these into labeled files with three tab-separated
columns, which are consumed by the training and evaluation scripts:
<source_password>\t<target_password>\t<encoded_edit_path>
How to run
All commands are run from the PassBERT/ directory and require a CUDA GPU.
Step 0. Pre-train BERT with masked LM
Build the char-level tokenizer and pre-train a BERT encoder on the password corpus:
python bert_pretrain.py
The pretrained BERT is included in ./bert_pretrain_chinese and ./bert_pretrain_english, which are trained using Tianya and Rockyou datasets respectively.
Step 1. Prepare data: generate in-place edit paths
Convert the raw (src, trg) pairs of each experiment into labeled edit-path files:
python editpath.py -c ../dataset/train/pseudo_train_data-popular.txt -o ./dataset/inplace_edits.txt
editpath.py is borrowed from the original PassBERT implementation for consistency.
Transformation into editpaths is needed for BOTH training and testing data. Remember to use –pseudo True for test sets, as PassBERT cannot generate editpaths for some password pairs (a limitation acknowledged by the original paper).
Optionally, you can also modify src/trg_pos, which stands for the positions of source/target passwords in a tab separated line, respectively.
Step 2. Local reuse training
python bert_local_train.py \
--train_file ./dataset/inplace_edits_local.txt \
--pretrain_bert_path ./bert_pretrain_chinese/checkpoint-7545 \
--save_path ./bert_local.pth \
--epochs 5
Step 3. Local-to-global training
Fine-tune each local model (with most layers frozen) on the global corpus:
python bert_global_train.py \
--train_file ./dataset/inplace_edits_global.txt \
--load_ckpt ./bert_local_last.pth \
--save_path ./bert_local_to_global.pth \
--epochs 1
Step 4. Evaluation
Compute the reuse-strength probability of every pair in a labeled test file
(one probability per line, written to --output_path):
python eval.py \
--test_file ./dataset/inplace_edits-targeted.txt \
--load_ckpt ./bert_local_to_global_last.pth \
--output_path ./test_result.txt \
Common Arguments
| Argument | Scripts | Description |
|---|---|---|
--train_file |
train / *_train | Labeled edit-path training file. |
--test_file |
eval | Labeled (or raw pair) test file. |
--load_ckpt |
train / eval | Checkpoint to initialize / evaluate from. |
--pretrain_bert_path |
bert_local_train | Path to the pretrained BERT directory. |
--save_path |
train / *_train | Where the checkpoint is saved (adds _last suffix). |
--output_path |
eval | Where results are written. |
--epochs |
train / *_train | Number of training epochs. |
--src_pos / --trg_pos |
eval | Column index of source / target in each line. |
Acknowledgment
The PassBERT paper can be found here, and their original TensorFlow PassBERT implementation can be accessed here.