Documentation
¶
Overview ¶
Package htpasswd classifies the password hashes in an Apache / nginx htpasswd basic-auth file.
An htpasswd file is a list of "username:hash" lines (RFC-less but stable, documented by the Apache httpd `htpasswd` and nginx auth_basic_user_file tooling). Each hash carries a self-identifying prefix that names the scheme: bcrypt ($2a/$2b/$2x/$2y$), the Apache-specific iterated MD5 ($apr1$), the crypt(3) family ($1$ MD5, $5$ SHA-256, $6$ SHA-512, $7$/$y$ yescrypt), the LDAP-style base64 digests ({SHA}, {SSHA}), the traditional 13-character DES crypt, and unhashed plaintext (the htpasswd -p mode). After an operator recovers such a file the question is "which of these are weak / crackable, and with what hashcat mode?" — this answers it without touching the hashes.
For each entry this surfaces the username, the recognised scheme, the matching hashcat -m mode, a strength tier (strong / weak / very weak / critical), and a per-entry note; the result summarises the weakest entries and flags any plaintext.
No confidently-wrong output: a scheme is named only from its unambiguous prefix (or, for DES crypt, the exact 13-char crypt-alphabet shape); an unrecognised field is surfaced as "plaintext / unknown" with a note, never guessed as a specific hash; the password is never cracked, only classified.
Wrap-vs-native: native — a line + prefix classifier, stdlib only, no new go.mod dependency. Anchored to real openssl / x-crypto / hashcat-example vectors (see the test).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Entry ¶
type Entry struct {
Line int `json:"line"`
Username string `json:"username"`
Scheme string `json:"scheme"`
HashcatMode string `json:"hashcat_mode,omitempty"`
Strength string `json:"strength"`
Hash string `json:"hash"`
Note string `json:"note,omitempty"`
}
Entry is one classified htpasswd line.
type Result ¶
type Result struct {
Format string `json:"format"`
EntryCount int `json:"entry_count"`
Entries []Entry `json:"entries,omitempty"`
WeakUsers []string `json:"weak_users,omitempty"`
PlaintextHit bool `json:"plaintext_present,omitempty"`
Malformed int `json:"malformed_lines,omitempty"`
Note string `json:"note"`
}
Result is the classified file.