Serializes go-passwd/hasher
hashers to / from a single string in a Django-style format.
go get github.com/go-passwd/marshallerimport (
"github.com/go-passwd/hasher"
"github.com/go-passwd/marshaller"
)
h, _ := hasher.New(hasher.TypeSHA256)
h.SetPassword("secret")
s, _ := marshaller.DjangoMarshaller.Marshal(h)
// s == "sha256$2048$<salt>$<hex-digest>"
restored, _ := marshaller.DjangoMarshaller.Unmarshal(s)
restored.Check("secret") // trueOutput adapts to whether iter and salt carry information:
| Iter | Salt | Format |
|---|---|---|
> 1 |
non-empty | code$iter$salt$digest |
> 1 |
empty | code$iter$digest |
<= 1 |
non-empty | code$salt$digest |
<= 1 |
empty | code$digest |
The default separator is $. The default DjangoMarshaller encodes
the digest as hex; Base64Marshaller encodes it as standard base64
(matching how Django's PBKDF2 stores hashes).
DjangoMarshaller—HexMarshaller{Separator: "$"}HexMarshaller{Separator: ":"}— same format with a different separatorBase64Marshaller{Separator: "$"}— base64 instead of hex
- The 3-segment form distinguishes iter from salt by trying to parse
the middle segment as an integer. A purely numeric salt would be
misread as
iter.randomstring.Generateproduces alphanumeric salts, so this only matters for hand-crafted salts. - The format is Django-style, not Django-compatible: real Django
MD5PasswordHasherandSHA1PasswordHasheruse a 3-fieldalgo$salt$hexshape with a single un-iterated digest.
To make a custom hasher.Hasher marshallable, implement
marshaller.Marshalable:
type Marshalable interface {
Code() string
HashIter() int
HashSalt() string
HashedPassword() []byte
}All hashers in go-passwd/hasher already do this.