go / expert
Snippet
Timing-sichere Token-Verifikation mit crypto/subtle
Ein naiver Vergleich wie bytes.Equal oder == auf zwei Strings bricht beim ersten Unterschied ab. Angreifer im Netz können diesen frühen Abbruch messen und einen MAC byteweise erraten — der passende Präfix wächst, sobald die Antwortzeit steigt. subtle.ConstantTimeCompare führt denselben Vergleich durch, liest aber stets alle Bytes und faltet das Ergebnis in einen einzigen Akkumulator: die Laufzeit hängt nur von der Länge, nicht vom Inhalt ab. Rückgabewert 1 bedeutet gleich, 0 bedeutet ungleich. Einsetzen bei HMAC-Tags, Passwort-Hashes, Session-Tokens und anderen geheimen Byte-Folgen.
snippet.go
go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package mainimport ("crypto/hmac""crypto/sha256""crypto/subtle""fmt")func sign(key, msg []byte) []byte {m := hmac.New(sha256.New, key)m.Write(msg)return m.Sum(nil)}func verify(provided, expected []byte) bool {// bytes.Equal short-circuits on the first mismatch and// would leak the matching prefix length via wall-clock// timing. ConstantTimeCompare always touches every byte.return subtle.ConstantTimeCompare(provided, expected) == 1}func main() {key := []byte("server-secret")want := sign(key, []byte("user=42"))got := make([]byte, len(want)) // attacker's guessfmt.Println("ok:", verify(got, want))}
Erklärung
1
m := hmac.New(sha256.New, key)
hmac.New bindet das Geheimnis an die Hash-Konstruktion; der entstehende Tag ist ohne key nicht fälschbar — genau das prüft der Verifier.
2
subtle.ConstantTimeCompare(provided, expected)
Iteriert über jedes Byte mit XOR-und-OR-Akkumulation. Unterschiedliche Längen liefern sofort 0, aber gleichlange Eingaben kosten stets dieselbe Zeit.
3
== 1
Die Funktion liefert int (1 oder 0) statt bool — der explizite Vergleich gegen 1 dokumentiert den Constant-Time-Vertrag an der Aufrufstelle.
4
got := make([]byte, len(want))
Ein Null-Byte-Kandidat steht stellvertretend für den Rateversuch eines Angreifers; produktiv käme er als X-Signature-Header über die Leitung.