package security import ( "encoding/base64" "encoding/hex" "errors" "os" "strings" "sync" ) var ( keyOnce sync.Once keyBuf []byte keyErr error ) // LoadEncryptionKey soporta raw (32 chars), base64(32 bytes) o hex(32 bytes). func LoadEncryptionKey() ([]byte, error) { keyOnce.Do(func() { v := strings.TrimSpace(os.Getenv("ENCRYPTION_KEY")) if v == "" { keyErr = errors.New("ENCRYPTION_KEY no definida") return } // 1) raw 32 chars if len(v) == 32 { keyBuf = []byte(v) return } // 2) base64 (std / url) if b, err := base64.StdEncoding.DecodeString(v); err == nil && len(b) == 32 { keyBuf = b return } if b, err := base64.URLEncoding.DecodeString(v); err == nil && len(b) == 32 { keyBuf = b return } // 3) hex (64 chars -> 32 bytes) if b, err := hex.DecodeString(v); err == nil && len(b) == 32 { keyBuf = b return } keyErr = errors.New("ENCRYPTION_KEY inválida: debe ser 32 chars raw, base64 de 32 bytes o hex de 32 bytes") }) return keyBuf, keyErr }