verifySignature static method
Verify a signature against expected values
payload - The original payload
secretKey - The secret key
receivedSignature - The signature to verify
receivedTimestamp - The timestamp from request
receivedNonce - The nonce from request
config - Configuration (must match generation config)
Returns Verification result
Example:
final verification = HmacOperations.verifySignature(
payload,
secretKey,
receivedSignature,
receivedTimestamp,
receivedNonce,
);
if (!verification.valid) {
print(verification.error);
}
Implementation
static VerificationResult verifySignature(
Map<String, dynamic> payload,
String secretKey,
String receivedSignature,
dynamic receivedTimestamp,
String receivedNonce, {
VerificationConfig config = const VerificationConfig(),
}) {
try {
// Generate expected signature with same config
final expectedResult = generateSignature(
payload,
secretKey,
config: config.copyWith(
customTimestamp: receivedTimestamp,
customNonce: receivedNonce,
),
);
// Check timestamp age
int timestampAge = 0;
if (receivedTimestamp is int ||
(receivedTimestamp is String &&
int.tryParse(receivedTimestamp) != null)) {
final now = DateTime.now().millisecondsSinceEpoch;
final timestampNum = receivedTimestamp is int
? receivedTimestamp
: int.parse(receivedTimestamp);
final timestampMs = timestampNum > 9999999999
? timestampNum
: timestampNum * 1000;
timestampAge = (now - timestampMs).abs();
if (timestampAge > config.timestampTolerance) {
return VerificationResult(
valid: false,
error:
'Timestamp expired. Age: ${timestampAge}ms, Tolerance: ${config.timestampTolerance}ms',
timestampAge: timestampAge,
);
}
}
// Timing-safe comparison
final signatureMatch = _timingSafeEqual(
receivedSignature,
expectedResult.signature,
);
if (!signatureMatch) {
return VerificationResult(
valid: false,
error: 'Signature mismatch',
expected: expectedResult.signature,
received: receivedSignature,
timestampAge: timestampAge,
);
}
return VerificationResult(valid: true, timestampAge: timestampAge);
} catch (e) {
return VerificationResult(
valid: false,
error: 'Verification failed: $e',
timestampAge: 0,
);
}
}