sec(sower): strengthen auth checksum against brute force

sumChecksum used binary.Uvarint over the digest, which stops at the
first byte with a clear continuation bit: ~50% of checksums collapsed
to 7 bits of entropy (~15 bits effective), making the auth check
brute-forceable. Take a fixed 64-bit window of a SHA-256 digest
instead. Wire layout is unchanged (checksum stays 8 bytes), and the
randomized field also removes the "high bytes all zero" fingerprint.
This commit is contained in:
wweir
2026-08-05 14:04:59 +08:00
parent bbab57f2a0
commit 48883b0783
+8 -5
View File
@@ -2,7 +2,7 @@ package sower
import (
"bytes"
"crypto/md5"
"crypto/sha256"
"encoding/binary"
"fmt"
"io"
@@ -93,11 +93,14 @@ func (s *Sower) Wrap(conn net.Conn, tgtHost string, tgtPort uint16) error {
}
func sumChecksum(target [maxDomainLength]byte, password []byte) uint64 {
h := md5.New()
h := sha256.New()
h.Write(target[:])
h.Write(password)
var checksum [md5.Size]byte
var checksum [sha256.Size]byte
h.Sum(checksum[:0])
checksumVal, _ := binary.Uvarint(checksum[:])
return checksumVal
// Take a fixed 64-bit window of the digest. binary.Uvarint would only
// consume bytes until the first continuation bit is clear (typically the
// first byte, ~50% of the time), collapsing the checksum to 7 bits of
// entropy and making the auth check brute-forceable.
return binary.BigEndian.Uint64(checksum[:8])
}