Skip to main content

HMAC Signature

Generates Hash-based Message Authentication Code (HMAC) signatures for data using a secret key. HMAC provides both data integrity verification and authentication, ensuring data hasn't been tampered with and confirming the sender's identity.

Common Properties

  • Name - The custom name of the node.
  • Color - The custom color of the node.
  • Delay Before (sec) - Waits in seconds before executing the node.
  • Delay After (sec) - Waits in seconds after executing node.
  • Continue On Error - Automation will continue regardless of any error. The default value is false.
info

If the ContinueOnError property is true, no error is caught when the project is executed, even if a Catch node is used.

Inputs

  • Data - The data to sign. Can be any string value (text, JSON, XML, etc.).

Options

  • Secret Key - The secret key credential used for HMAC generation. Retrieved from Robomotion Vault.
  • Hash Function - The underlying hash algorithm to use:
    • md5 - MD5-based HMAC (fast but less secure)
    • sha1 - SHA-1-based HMAC (legacy)
    • sha256 - SHA-256-based HMAC (recommended)
    • sha512 - SHA-512-based HMAC (high security)

Output

  • signature - The HMAC signature in hexadecimal format.

How It Works

HMAC combines a secret key with data and a hash function to create an authentication code:

  1. Receives the data to sign and retrieves the secret key from vault
  2. Validates that the secret key is available and properly formatted
  3. Creates an HMAC instance using the selected hash function and secret key
  4. Processes the data through the HMAC algorithm
  5. Generates the authentication code
  6. Encodes the signature as hexadecimal string
  7. Returns the HMAC signature

HMAC signatures are deterministic - same data and key always produce the same signature.

Example Usage

API Request Authentication

// Sign API request for authentication
const requestData = JSON.stringify({
action: "transfer",
amount: 1000,
timestamp: Date.now()
});

// Use HMAC Signature node with SHA-256
// Secret key from vault: api_secret_key
const signature = "{{msg.signature}}";

// Send request with signature
// POST /api/transfer
// Headers: {
// "X-Signature": signature,
// "Content-Type": "application/json"
// }
// Body: requestData

Webhook Signature Verification

// Generate signature for outgoing webhook
const webhookPayload = JSON.stringify({
event: "order.created",
orderId: "12345",
customer: "john@example.com",
timestamp: Date.now()
});

// Use HMAC Signature node
// Secret shared with webhook receiver
const signature = "{{msg.signature}}";

// Send webhook with signature
// Receiver can verify using same secret key

Data Integrity Protection

// Protect data integrity in database
const sensitiveData = JSON.stringify({
userId: "user123",
balance: 5000,
lastUpdated: Date.now()
});

// Use HMAC Signature node with SHA-256
const dataSignature = "{{msg.signature}}";

// Store both data and signature
// database.save({
// data: sensitiveData,
// signature: dataSignature
// });

// Later, verify data hasn't been tampered with
// Recalculate signature and compare

Secure Token Generation

// Create secure session token
const tokenData = JSON.stringify({
userId: "user123",
sessionId: "sess_abc123",
expiresAt: Date.now() + 3600000 // 1 hour
});

// Use HMAC Signature node
const tokenSignature = "{{msg.signature}}";

// Combine data and signature for token
const secureToken = Buffer.from(tokenData).toString('base64') + '.' + tokenSignature;

// Verify token by recalculating signature

Message Authentication

// Authenticate messages between systems
const message = "EXECUTE_BACKUP_NOW";
const timestamp = Date.now();
const messageData = message + "|" + timestamp;

// Use HMAC Signature node with SHA-512
const messageSignature = "{{msg.signature}}";

// Send message with signature and timestamp
// Receiver verifies:
// 1. Timestamp is recent (prevent replay attacks)
// 2. Signature matches (authenticate sender)

File Integrity with Authentication

// Create authenticated file hash
// 1. Use File Hash node to hash file
const fileHash = "{{msg.hash}}";

// 2. Use HMAC Signature node to sign the hash
const authenticatedHash = "{{msg.signature}}";

// Store authenticated hash in catalog
// This proves both file integrity AND who created the hash

Requirements

  • Valid secret key stored in Robomotion Vault
  • Secret key should be cryptographically random (use Generate Key node)
  • Data can be any string (typically JSON, XML, or plain text)
  • Same secret key required for verification

Error Handling

The node will return errors in the following cases:

  • Missing secret key - Secret key credential not found in vault
  • Invalid secret key format - Secret key is not a valid string
  • Empty data - No data provided to sign (empty string is valid)

Security Best Practices

  • Use SHA-256 or SHA-512 - Avoid MD5 and SHA-1 for production use
  • Secure secret storage - Always store secret keys in Robomotion Vault
  • Strong secrets - Use cryptographically random keys (256+ bits)
  • Rotate keys - Change secret keys periodically
  • Unique keys per purpose - Use different keys for different applications
  • Constant-time comparison - Compare signatures in constant time to prevent timing attacks
  • Include timestamp - Add timestamps to prevent replay attacks
  • Never log secrets - Don't write secret keys to logs
  • Limit key access - Only authorized flows should access secret keys

HMAC vs Other Methods

HMAC vs Simple Hash

  • Hash: Only verifies data integrity, anyone can calculate
  • HMAC: Verifies integrity AND authenticates sender (requires secret)

HMAC vs RSA Signature

  • HMAC: Faster, symmetric (same key for sign and verify)
  • RSA: Slower, asymmetric (private key signs, public key verifies)

HMAC vs Encryption

  • HMAC: Authenticates data, doesn't hide it
  • Encryption: Hides data, doesn't authenticate it
  • Best practice: Use both (encrypt-then-MAC)

Common Use Cases

  • API Authentication - Sign API requests to prove identity
  • Webhook Verification - Verify webhooks from third-party services
  • Data Integrity - Detect tampering in stored data
  • Message Authentication - Authenticate messages between systems
  • Session Tokens - Create and verify secure session tokens
  • Payment Processing - Sign payment requests for PCI compliance
  • Configuration Protection - Detect unauthorized configuration changes
  • JWT Alternative - Create simple authenticated tokens

Algorithm Selection

  • Good balance of security and performance
  • Widely supported and trusted
  • Suitable for most applications
  • Output: 64 hex characters

SHA-512 (High Security)

  • Higher security margin
  • Slower than SHA-256
  • Better for high-security applications
  • Output: 128 hex characters

SHA-1 (Legacy)

  • Deprecated for security
  • Only use for legacy compatibility
  • Output: 40 hex characters
  • Cryptographically broken
  • Only use for non-security purposes
  • Fastest option
  • Output: 32 hex characters

Tips for Effective Use

  • Always use the same hash function for signing and verification
  • Include timestamps to prevent replay attacks
  • Combine with nonces for one-time use signatures
  • Store signatures alongside data for verification
  • Use base64 encoding if hexadecimal is too long
  • Implement signature expiration for time-sensitive data
  • Test signature generation and verification in development
  • Document which secret key is used for each purpose

Verification Example

// Sender side (creates signature)
const data = "Important message";
// Use HMAC Signature node
const signature = "{{msg.signature}}";
// Send: {data: data, signature: signature}

// Receiver side (verifies signature)
const received = {
data: "Important message",
signature: "abc123def456..."
};

// Use HMAC Signature node with same secret and data
const expectedSignature = "{{msg.signature}}";

// Compare signatures
if (received.signature === expectedSignature) {
console.log("Signature valid - message authenticated");
} else {
console.log("WARNING: Invalid signature - message may be tampered!");
}

Integration Patterns

Encrypt-then-MAC Pattern

// Best practice: Encrypt data, then HMAC the ciphertext
// 1. Encrypt sensitive data
const plaintext = "Secret information";
// Use Encrypt Text node
const ciphertext = "{{msg.cipher_text}}";

// 2. Sign the ciphertext with HMAC
// Use HMAC Signature node
const signature = "{{msg.signature}}";

// 3. Send both
// {ciphertext: ciphertext, signature: signature}

// Receiver:
// 1. Verify signature first
// 2. Only decrypt if signature is valid

Request-Response Authentication

// Request
const requestId = "req_" + Date.now();
const requestData = {id: requestId, action: "getData"};
// Use HMAC Signature node
const requestSig = "{{msg.signature}}";

// Response
const responseData = {
requestId: requestId,
data: "Response data",
timestamp: Date.now()
};
// Use HMAC Signature node
const responseSig = "{{msg.signature}}";

// Both sides verify signatures

Performance Considerations

  • HMAC is very fast for small to medium data
  • SHA-256 HMAC: ~500 MB/s on modern hardware
  • SHA-512 HMAC: ~700 MB/s on 64-bit systems
  • For large data, consider hashing first, then HMAC the hash
  • Signature generation is CPU-bound
  • Text Hash - Calculate simple hashes without authentication
  • Sign - Create RSA digital signatures (asymmetric)
  • Verify - Verify RSA signatures
  • Generate Key - Generate secret keys for HMAC
  • Encrypt Text - Combine with encryption for confidentiality