package signature import ( "crypto/hmac" "crypto/sha512" "encoding/hex" "errors" "strings" "time" "edge-infra.dev/pkg/edge/datasync/internal/config" ) type MessageSignatureContext struct { MessageID string MessageType string Payload []byte Timestamp time.Time } func Generate(sharedKey string, secretKey string, messageContext MessageSignatureContext, organizationName string) (string, error) { if sharedKey == "" || secretKey == "" { return "", errors.New("failed to sign message. missing keys") } signableContent := getSignableContent(messageContext, organizationName) // if err != nil { // return "", fmt.Errorf("failed to sign content. %v", err.Error()) // } authenticationHash := GenerateHmac(secretKey, signableContent, messageContext.Timestamp) return sharedKey + ":" + authenticationHash, nil } func getSignableContent(messageContext MessageSignatureContext, organizationName string) string { appKey := config.GetAppKey() values := make([]string, 0) // h := md5.New() // _, err := io.WriteString(h, string(messageContext.Payload)) // if err != nil { // return "", fmt.Errorf("failed to write payload with md5. %v", err.Error()) // } // md5Checksum := h.Sum(nil) values = append(values, appKey) // values = append(values, string(md5Checksum)) values = append(values, string(messageContext.Payload)) // TODO: maybe dont values = append(values, messageContext.MessageID) values = append(values, organizationName) valuesWithContent := make([]string, 0) for _, value := range values { if value != "" { valuesWithContent = append(valuesWithContent, value) } } signableContent := strings.Join(valuesWithContent, "\n") //fmt.Println(signableContent) return signableContent } func GenerateHmac(secretKey string, signableContent string, timestamp time.Time) string { iso8601Timestamp := timestamp.Format(time.RFC3339) uniqueKey := secretKey + iso8601Timestamp // Create a new HMAC by defining the hash type and the key (as byte array) h := hmac.New(sha512.New, []byte(uniqueKey)) // Write Data to it _, err := h.Write([]byte(signableContent)) if err != nil { return "" } // Get result and encode as hexadecimal string sha := hex.EncodeToString(h.Sum(nil)) return sha }