hmac.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package audit
  2. import (
  3. "crypto/hmac"
  4. "encoding/hex"
  5. "encoding/json"
  6. udeModel "udeServer/internal/model"
  7. "github.com/tjfoc/gmsm/sm3"
  8. )
  9. // CalculateHMAC computes the HMAC-SM3 of the log entry (without the
  10. // audit-state / HMAC / timestamp / id fields) with the given secret key.
  11. func CalculateHMAC(entry *udeModel.TSystemLog, secretKey string, macBytes []byte) (string, error) {
  12. // 解析log对象为字节数组,并清空旧的Hmac
  13. data, err := generateHmacBytes(entry)
  14. if err != nil {
  15. return "", err
  16. }
  17. // 计算Hmac
  18. mac := hmac.New(sm3.New, []byte(secretKey))
  19. mac.Write(data)
  20. // 写入复用缓冲区,只清空长度,不清空容量
  21. entryHmac := mac.Sum(macBytes[:0])
  22. return hex.EncodeToString(entryHmac), nil
  23. }
  24. // generateHmacBytes marshals the entry and strips the fields excluded from
  25. // the MAC computation. NOTE: TSystemLog has no json tags on purpose, so the
  26. // marshalled keys equal the Go field names and this exclusion list stays in
  27. // sync with the struct definition.
  28. func generateHmacBytes(entry any) ([]byte, error) {
  29. data, err := json.Marshal(entry)
  30. if err != nil {
  31. return nil, err
  32. }
  33. var m map[string]interface{}
  34. if err = json.Unmarshal(data, &m); err != nil {
  35. return nil, err
  36. }
  37. // 移除Hmac无关字段
  38. delete(m, "AuditStatus")
  39. delete(m, "HMac")
  40. delete(m, "CreatedAt")
  41. delete(m, "Id")
  42. signContent, err := json.Marshal(m)
  43. if err != nil {
  44. return nil, err
  45. }
  46. return signContent, nil
  47. }