package crypto import ( "strings" "testing" ) // TestEncryptDecryptRoundTrip 覆盖 AES-GCM 加解密往返(含空串与 Unicode)。 func TestEncryptDecryptRoundTrip(t *testing.T) { cases := []string{"", "hello", "a-much-longer-secret-with-unicode-密码-🔑"} for _, plain := range cases { enc, err := Encrypt(plain) if err != nil { t.Fatalf("Encrypt(%q) error: %v", plain, err) } dec, err := Decrypt(enc) if err != nil { t.Fatalf("Decrypt(%q) error: %v", plain, err) } if dec != plain { t.Fatalf("round-trip mismatch: got %q want %q", dec, plain) } } } // TestDecryptTamperedFails 验证 GCM 认证:篡改密文必须解密失败。 func TestDecryptTamperedFails(t *testing.T) { enc, err := Encrypt("secret-value") if err != nil { t.Fatal(err) } if len(enc) < 4 { t.Fatal("ciphertext too short") } // 翻转末尾两个 base64 字符,破坏 GCM 认证标签 tampered := enc[:len(enc)-2] + "AA" if _, err := Decrypt(tampered); err == nil { t.Fatal("expected Decrypt to fail on tampered ciphertext, got nil") } } // TestEncryptFieldContract 是 M2 的回归保护: // EncryptField 绝不能返回 "ENC_ERR:" 哨兵(否则 DecryptField 会把它当明文凭证用), // 只能返回 ""(空输入)或 "ENC:" 前缀;且与 DecryptField 可往返。 func TestEncryptFieldContract(t *testing.T) { enc, err := EncryptField("super-secret") if err != nil { t.Fatalf("EncryptField error: %v", err) } if !strings.HasPrefix(enc, "ENC:") { t.Fatalf("EncryptField must return ENC:-prefixed value, got %q", enc) } if enc == "ENC_ERR:" { t.Fatal("EncryptField returned legacy sentinel ENC_ERR: (M2 regression)") } if got := DecryptField(enc); got != "super-secret" { t.Fatalf("DecryptField round-trip: got %q want super-secret", got) } if !IsEncryptedField(enc) { t.Fatal("IsEncryptedField should be true for ENC: value") } if IsEncryptedField("plain-value") { t.Fatal("IsEncryptedField should be false for plain value") } // 空输入约定 if enc, err := EncryptField(""); enc != "" || err != nil { t.Fatalf("EncryptField(\"\") = (%q,%v), want (\"\",nil)", enc, err) } } // TestEncryptFieldRandomNonce 同一明文两次加密应产生不同密文(随机 nonce)。 func TestEncryptFieldRandomNonce(t *testing.T) { a, _ := EncryptField("same-secret") b, _ := EncryptField("same-secret") if a == b { t.Fatal("expected different ciphertexts due to random nonce") } }