7.6 KiB
HMAC File Server Authentication Protocol Specifications
This document outlines the different authentication protocols supported by the HMAC File Server for secure file uploads and downloads. The server supports multiple authentication methods to ensure backward compatibility while providing enhanced security features.
Overview
The HMAC File Server supports two primary authentication mechanisms:
- HMAC-based Authentication (Multiple versions: v1, v2, token, v3)
- JWT Authentication (Bearer tokens)
All protocols use SHA256 hashing and require a shared secret key configured on the server.
HMAC Authentication Protocols
Common Elements
- Algorithm: HMAC-SHA256
- Secret: Shared secret key configured in
[security]
section - Transport: URL query parameters for HMAC, headers for signatures
- Encoding: Hexadecimal encoding for HMAC values
Legacy v1 Protocol (v
parameter)
Overview: The original HMAC authentication protocol.
URL Format:
PUT /filename.ext?v=HMAC_SIGNATURE
Message Construction:
fileStorePath + "\x20" + contentLength
Example:
# For file "test.txt" with 1024 bytes
# Message: "test.txt\x201024"
curl -X PUT "http://localhost:8080/test.txt?v=a1b2c3d4..." --data-binary @test.txt
Implementation Notes:
- Uses space character (
\x20
) as separator - Content-Length header must be accurate
- Simplest protocol, minimal metadata validation
Enhanced v2 Protocol (v2
parameter)
Overview: Enhanced version including content type validation.
URL Format:
PUT /filename.ext?v2=HMAC_SIGNATURE
Message Construction:
fileStorePath + "\x00" + contentLength + "\x00" + contentType
Example:
# For file "document.pdf" with 2048 bytes
# Message: "document.pdf\x002048\x00application/pdf"
curl -X PUT "http://localhost:8080/document.pdf?v2=e5f6g7h8..." --data-binary @document.pdf
Implementation Notes:
- Uses null characters (
\x00
) as separators - Content-Type automatically detected from file extension
- Fallback to "application/octet-stream" for unknown extensions
Token Protocol (token
parameter)
Overview: Alternative parameter name for v2-style authentication.
URL Format:
PUT /filename.ext?token=HMAC_SIGNATURE
Message Construction: Same as v2 protocol
fileStorePath + "\x00" + contentLength + "\x00" + contentType
Example:
curl -X PUT "http://localhost:8080/image.jpg?token=i9j0k1l2..." --data-binary @image.jpg
Implementation Notes:
- Identical to v2 protocol but uses
token
parameter - Useful for clients that prefer different parameter naming
v3 Protocol - mod_http_upload_external Compatible (v3
parameter)
Overview: Specifically designed for Prosody's mod_http_upload_external
compatibility with expiration support.
URL Format:
PUT /path/to/file.ext?v3=HMAC_SIGNATURE&expires=UNIX_TIMESTAMP
Message Construction:
METHOD + "\n" + expires + "\n" + requestPath
Example:
# Current timestamp: 1717804800
# Message: "PUT\n1717804800\n/upload/myfile.txt"
curl -X PUT "http://localhost:8080/upload/myfile.txt?v3=m3n4o5p6...&expires=1717804800" --data-binary @myfile.txt
Verification Process:
- Extract
v3
signature andexpires
timestamp - Validate
expires
is in the future - Construct message:
"{METHOD}\n{expires}\n{path}"
- Calculate HMAC-SHA256 of message
- Compare with provided signature
Implementation Notes:
- Includes expiration timestamp validation
- Prevents replay attacks through time-based validation
- Path-only signing (no query parameters in signed message)
- HTTP method is part of the signed message
JWT Authentication
Overview: Token-based authentication using JSON Web Tokens.
Configuration:
[security]
enablejwt = true
jwtsecret = "your-256-bit-secret"
jwtalgorithm = "HS256"
jwtexpiration = "24h"
Header Format:
Authorization: Bearer JWT_TOKEN
Fallback Query Parameter:
GET /file.txt?token=JWT_TOKEN
Example Usage:
# Header-based JWT
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." http://localhost:8080/file.txt
# Query parameter fallback
curl "http://localhost:8080/file.txt?token=eyJhbGciOiJIUzI1NiIs..."
JWT Claims: Standard JWT claims (exp, iat, iss, etc.) as configured.
POST Upload Authentication
X-Signature Header Method
Overview: For multipart form uploads via POST requests.
Header Format:
X-Signature: HMAC_OF_REQUEST_PATH
Message Construction:
requestPath (e.g., "/upload")
Example:
# HMAC of "/upload"
curl -X POST \
-H "X-Signature: CALCULATED_HMAC" \
-F 'file=@myfile.txt' \
http://localhost:8080/upload
Authentication Priority and Fallbacks
The server checks authentication in the following order:
-
JWT Authentication (if
enablejwt = true
)- Authorization header (Bearer token)
- Query parameter
token
-
HMAC Authentication (if JWT disabled or not found)
- X-Signature header (for POST uploads)
- v3 protocol (with expires validation)
- v2 protocol
- token protocol
- v1 protocol (legacy)
Security Considerations
HMAC Protocols
- Secret Management: Use strong, randomly generated secrets
- Time Validation: v3 protocol includes expiration to prevent replay attacks
- Content Validation: v2/token protocols include content-type validation
- Path Sanitization: All protocols validate and sanitize file paths
JWT Authentication
- Token Expiration: Configure appropriate expiration times
- Secret Rotation: Regularly rotate JWT signing keys
- Algorithm Security: Default HS256 is secure for most use cases
- Transport Security: Always use HTTPS in production
General Security
- HTTPS Only: Use TLS encryption for all production deployments
- Rate Limiting: Implement reverse proxy rate limiting
- File Validation: Configure allowed file extensions
- Virus Scanning: Enable ClamAV integration for malware detection
- Access Logs: Monitor authentication failures and suspicious activity
Migration Guide
From v1 to v2
- Update HMAC calculation to include content type
- Change separator from
\x20
to\x00
- No breaking changes in URL structure
From HMAC to JWT
- Set
enablejwt = true
in configuration - Generate JWT tokens server-side or use external auth provider
- HMAC authentication remains available as fallback
Adding v3 Support
- Implement expiration timestamp generation
- Update HMAC calculation to include HTTP method and expiration
- Useful for mod_http_upload_external compatibility
Example Implementations
Client-Side HMAC Generation (Python)
import hmac
import hashlib
import time
def generate_v3_signature(secret, method, expires, path):
message = f"{method}\n{expires}\n{path}"
signature = hmac.new(
secret.encode(),
message.encode(),
hashlib.sha256
).hexdigest()
return signature
# Example usage
secret = "your-hmac-secret"
expires = int(time.time()) + 3600 # 1 hour from now
signature = generate_v3_signature(secret, "PUT", expires, "/upload/file.txt")
Server-Side Validation (Reference)
See the main.go file for complete implementation details of all validation functions:
validateHMAC()
: Legacy v1, v2, and token protocolsvalidateV3HMAC()
: v3 protocol with expirationvalidateJWTFromRequest()
: JWT validation
This specification ensures consistent implementation across clients and provides multiple authentication options for different use cases and security requirements.