hmac_auth_builder 0.0.1
hmac_auth_builder: ^0.0.1 copied to clipboard
HMAC-based request signing for Dart and Flutter, designed for secure API authentication and webhook verification. The library produces signatures that are compatible with the Node.js package `hmac-aut [...]
hmac_auth_builder #
HMAC-based request signing for Dart and Flutter, designed for secure API authentication and webhook verification. The library produces signatures that are compatible with the Node.js package hmac-auth-builder, enabling consistent verification between mobile clients and backend services.
Overview #
hmac_auth_builder provides:
- Deterministic HMAC signatures for request authentication.
- Canonical string signing to avoid JSON serialization differences.
- Multiple hash algorithms and encodings.
- Timestamp and nonce support for replay protection.
- Full interoperability with the Node.js
hmac-auth-builderpackage.
It is intended for:
- Mobile apps (Flutter) calling secure backend APIs.
- Clients that must generate signatures verified by a Node.js service.
- Webhook providers/consumers that need cross-platform HMAC signing.
Installation #
Add the dependency in pubspec.yaml:
dependencies:
hmac_auth_builder: ^1.0.0
Then run:
flutter pub get
Basic Usage #
import 'package:hmac_auth_builder/hmac_operations.dart';
void main() {
final payload = {
'transaction_id': 'TXN-2026-001',
'amount': 5000,
'currency': 'USD',
};
const secretKey = 'your-secret-key';
// Generate signature
final result = HmacOperations.generateSignature(
payload,
secretKey,
);
print('Timestamp: ${result.timestamp}');
print('Nonce: ${result.nonce}');
print('Signature: ${result.signature}');
print('Algorithm: ${result.algorithm}');
print('Canonical: ${result.canonicalString}');
}
Verifying a Signature #
Use this when you receive a signed request in a Dart server, or for local verification in tests.
import 'package:hmac_auth_builder/hmac_operations.dart';
void verifyRequest(
Map<String, dynamic> payload,
String secretKey,
String receivedSignature,
String receivedTimestamp,
String receivedNonce,
) {
final verification = HmacOperations.verifySignature(
payload,
secretKey,
receivedSignature,
receivedTimestamp,
receivedNonce,
config: const VerificationConfig(
timestampTolerance: 180000, // 3 minutes in milliseconds
),
);
if (!verification.valid) {
throw StateError('Invalid signature: ${verification.error}');
}
// Proceed with handling the request
}
Cross-Platform Compatibility (Node.js ↔ Dart) #
The library is designed to produce exactly the same canonical string and signature as the Node.js implementation, given identical inputs.
Dart:
import 'package:hmac_auth_builder/hmac_operations.dart';
void main() {
final payload = {
'property_id': 'PROP123',
'aadhaar_number': '123456789012',
'consent': true,
};
const secret = 'ALT_TM_ADMINNLT65XER';
const fixedTimestamp = 1700000000000;
const fixedNonce = 'test-nonce-12345';
final result = HmacOperations.generateSignature(
payload,
secret,
config: const HmacConfig(
customTimestamp: fixedTimestamp,
customNonce: fixedNonce,
),
);
print('Timestamp: ${result.timestamp}');
print('Nonce: ${result.nonce}');
print('Canonical: ${result.canonicalString}');
print('Signature: ${result.signature}');
}
Node.js (hmac-auth-builder):
import { HmacOperations } from "hmac-auth-builder";
const payload = {
property_id: "PROP123",
aadhaar_number: "123456789012",
consent: true,
};
const secret = "ALT_TM_ADMINNLT65XER";
const fixedTimestamp = 1700000000000;
const fixedNonce = "test-nonce-12345";
const result = HmacOperations.generateSignature(payload, secret, {
customTimestamp: fixedTimestamp,
customNonce: fixedNonce,
});
console.log("Timestamp:", result.timestamp);
console.log("Nonce:", result.nonce);
console.log("Canonical:", result.canonicalString);
console.log("Signature:", result.signature);
The canonical string and signature from Dart and Node.js should match byte-for-byte when you use the same payload, secret, timestamp, and nonce.
Configuration #
HmacConfig lets you control how signatures are produced.
const config = HmacConfig(
signatureMethod: 'canonical', // 'canonical' or 'json'
separator: '|', // separator between fields
canonicalFields: ['user_id', 'amount', 'currency'],
hashAlgorithm: 'sha256', // 'sha256', 'sha512', 'sha384', 'sha1', 'md5'
encoding: 'hex', // 'hex', 'base64', 'base64url'
timestampFormat: 'milliseconds', // 'milliseconds', 'seconds', 'unix', 'iso8601'
nonceFormat: 'uuid-v4', // 'uuid-v4', 'uuid-v1', 'random-hex', 'random-base64', 'custom'
includeTimestampInSignature: true,
includeNonceInSignature: true,
sortJsonKeys: true,
);
Example with Custom Configuration #
final result = HmacOperations.generateSignature(
{
'user_id': '123',
'amount': 5000,
'currency': 'INR',
},
'your-secret-key',
config: const HmacConfig(
hashAlgorithm: 'sha512',
encoding: 'base64',
canonicalFields: ['user_id', 'amount', 'currency'],
separator: '::',
),
);
Typical Flutter Integration #
A simple pattern for signing API requests from a Flutter app:
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:hmac_auth_builder/hmac_operations.dart';
class ApiClient {
ApiClient(this._baseUrl, this._secretKey);
final String _baseUrl;
final String _secretKey;
Future<http.Response> post(
String path,
Map<String, dynamic> payload,
) async {
final auth = HmacOperations.generateSignature(
payload,
_secretKey,
);
final uri = Uri.parse('$_baseUrl$path');
return http.post(
uri,
headers: {
'Content-Type': 'application/json',
'X-Timestamp': auth.timestamp.toString(),
'X-Nonce': auth.nonce,
'X-Signature': auth.signature,
},
body: jsonEncode(payload),
);
}
}
On the backend, you verify the same headers and payload using the Node.js hmac-auth-builder package.
Testing #
Run the package tests:
flutter test
For local cross-platform verification, you can:
- Generate a signature in Dart with fixed
customTimestampandcustomNonce. - Generate a signature in Node.js with the same fixed values.
- Confirm that canonical string and signature match.
License #
This package is available under the MIT License. See the LICENSE file for details.
👨💻 Author #
Gunjan Sharma #
Full Stack Architect & Security Engineer
Building secure, scalable systems for fintech and enterprise applications. Specializing in API security, microservices architecture, and blockchain integrations.
Open for:
- 🔐 Security audits and consulting
- 🚀 System architecture reviews
- 💼 Freelance projects
- 🤝 Technical collaborations
📄 License #
MIT License - see LICENSE file for details.
Copyright © 2026 Gunjan Sharma
🙏 Acknowledgments #
- Inspired by Stripe's webhook signature verification
- HMAC implementation follows RFC 2104
- Timing-safe comparison based on OpenSSL's approach