package hmac import ( "testing" "time" ) func TestSignVerifyRoundTrip(t *testing.T) { secret := "topsecret" body := `{"brand_uid":"001DESke","source_url":"https://vogue.com/x"}` ts := tsNow() nonce := "abc123nonce" sig := Sign(secret, ts, nonce, body) if !Verify(secret, body, sig, ts, nonce, DefaultTTL) { t.Fatal("valid signature should verify") } // 篡改 body → 失败 if Verify(secret, body+"x", sig, ts, nonce, DefaultTTL) { t.Fatal("tampered body should fail") } // 错误密钥 → 失败 if Verify("wrong", body, sig, ts, nonce, DefaultTTL) { t.Fatal("wrong secret should fail") } // 缺头 → 失败 if Verify(secret, body, "", ts, nonce, DefaultTTL) { t.Fatal("missing header should fail") } } func TestVerifyRejectsStaleTimestamp(t *testing.T) { secret := "s" body := "{}" // 早于窗口 old := timeNowMinus(600) nonce := "n1" sig := Sign(secret, old, nonce, body) if Verify(secret, body, sig, old, nonce, DefaultTTL) { t.Fatal("stale timestamp should be rejected") } // 晚于窗口(未来太多) future := timeNowPlus(600) sig2 := Sign(secret, future, nonce, body) if Verify(secret, body, sig2, future, nonce, DefaultTTL) { t.Fatal("future timestamp beyond window should be rejected") } } // 简易时间助手(避免直接依赖 time.Now 的不可控) func tsNow() string { return itoa(int64(time.Now().Unix())) } func timeNowMinus(sec int) string { return itoa(int64(time.Now().Unix()) - int64(sec)) } func timeNowPlus(sec int) string { return itoa(int64(time.Now().Unix()) + int64(sec)) } func itoa(v int64) string { if v == 0 { return "0" } neg := v < 0 if neg { v = -v } buf := [20]byte{} i := len(buf) for v > 0 { i-- buf[i] = byte('0' + v%10) v /= 10 } if neg { i-- buf[i] = '-' } return string(buf[i:]) }