DEV Community

Clavin June
Clavin June

Posted on • Originally published at clavinjune.dev on

Comparing String to Avoid Time Based Attacks

Sunday Snippet #10 comparing string to avoid time based attacks

Code

package foo_test import ( "crypto/rand" "crypto/subtle" "fmt" "strings" "testing" "time" ) var ( a []byte length int = 100000 batch int = length / 10 ) func init() { a = make([]byte, length, length) rand.Read(a) } func getCopied(changedIndex int) []byte { b := make([]byte, length, length) copy(b, a) b[changedIndex] = byte(1) return b } func wrapper(fn func(a, b []byte) bool) { for i := length - 1; i > 0; i -= batch { b := getCopied(i) n := time.Now() fn(a, b) m := time.Since(n) fmt.Printf("Differences at Index: %d, time takes: %s\n", i, m.String()) } } func Cmp(a, b []byte) bool { return string(a) == string(b) } func CmpSub(a, b []byte) bool { return subtle.ConstantTimeCompare(a, b) == 1 } func TestCmp(t *testing.T) { fmt.Printf("length of chars: %d\n", length) fmt.Println("comparison using: string(a) == string(b)") wrapper(Cmp) fmt.Println(strings.Repeat("=", 60)) fmt.Println("comparison using: subtle.ConstantTimeCompare(a, b) == 1") wrapper(CmpSub) } 
Enter fullscreen mode Exit fullscreen mode

Test

$ go version go version go1.18 darwin/arm64 $ go test . -v -count=1 === RUN TestCmp length of chars: 100000 comparison using: string(a) == string(b) Differences at Index: 99999, time takes: 2.875µs Differences at Index: 89999, time takes: 2.583µs Differences at Index: 79999, time takes: 2.375µs Differences at Index: 69999, time takes: 2.209µs Differences at Index: 59999, time takes: 1.75µs Differences at Index: 49999, time takes: 1.5µs Differences at Index: 39999, time takes: 1.209µs Differences at Index: 29999, time takes: 958ns Differences at Index: 19999, time takes: 666ns Differences at Index: 9999, time takes: 375ns ============================================================ comparison using: subtle.ConstantTimeCompare(a, b) == 1 Differences at Index: 99999, time takes: 50.792µs Differences at Index: 89999, time takes: 50.583µs Differences at Index: 79999, time takes: 50.958µs Differences at Index: 69999, time takes: 50.709µs Differences at Index: 59999, time takes: 51µs Differences at Index: 49999, time takes: 51.333µs Differences at Index: 39999, time takes: 55.875µs Differences at Index: 29999, time takes: 50.75µs Differences at Index: 19999, time takes: 51.709µs Differences at Index: 9999, time takes: 51.167µs --- PASS: TestCmp (0.00s) PASS ok example 0.092s 
Enter fullscreen mode Exit fullscreen mode

Conclusion

Thus, subtle.ConstantTimeCompare(a, b) == 1 is more likely to be safe to use to avoid time-based attacks. Also, to avoid the length of the string to be guessed, you can hash the string first.

Top comments (0)