Skip to content

Instantly share code, notes, and snippets.

@rlaphoenix
Last active October 12, 2025 19:13
Show Gist options
  • Save rlaphoenix/c59d853630728dc1f3e1173563acad2e to your computer and use it in GitHub Desktop.
Save rlaphoenix/c59d853630728dc1f3e1173563acad2e to your computer and use it in GitHub Desktop.
Windows Script to brute force a GnuPG secret key (basic, slow, single-threaded) (a-z0-9 only)
# Download GnuPG through GPG4WIN: https://www.gpg4win.org
# Add "C:\Program Files (x86)\GnuPG\bin" to System PATH variable
# Before running this script, do gpg-agent --allow-loopback-pinentry
# If it says "gpg-agent running and available" do "gpgconf --kill gpg-agent" and try again
param (
[string]$KeyID, # GPG Key ID to brute force
[int]$Digits = 8, # Number of digits in passphrase (default 3)
[long]$StartIndex = 0 # Resume point (default 0)
)
$chars = @((0..9) | ForEach-Object { [string]$_ }) + @([char[]]"abcdefghijklmnopqrstuvwxyz")
function Convert-ToBase36Lower {
param($num, [int]$length)
$res = ""
for ($i = 0; $i -lt $length; $i++) {
$digit = [int]($num % 36)
$res = $chars[$digit] + $res
$num = [math]::Floor($num / 36)
}
return $res
}
$max = 1
for ($i = 0; $i -lt $Digits; $i++) { $max *= 36 }
$max -= 1
if ($StartIndex -lt 0 -or $StartIndex -gt $max) {
Write-Error "StartIndex out of range (0..$max)"
exit 1
}
$ret = 1
for ($idx = $StartIndex; $idx -le $max; $idx++) {
$pass = Convert-ToBase36Lower $idx $Digits
$gpg_test = & gpg --default-key $KeyID -n --passphrase "$pass" --pinentry-mode loopback --clearsign NUL 2>&1
$ret = $LASTEXITCODE
if ($ret -eq 0) {
Write-Host "Found! Passphrase: $pass"
break
} elseif ($gpg_test -match "Bad passphrase") {
Write-Host -NoNewline "."
if (($idx % 1000) -eq 0) {
Write-Host ""
Write-Host "Summary: $StartIndex-$idx/$max ($pass)"
}
} else {
Write-Host "Else " + $ret + " " + $gpg_test
exit $ret
}
}
if ($ret -ne 0) {
Write-Host "Not found :("
exit -1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment