decryptEnvelope method
Decrypt and verify envelope
Implementation
String decryptEnvelope(
Map<String, dynamic> envelope,
String receiverId, {
String? timestamp,
}) {
final time = timestamp ?? envelope['timestamp'];
final key = keyResonance(envelope['senderId'], timestamp: time);
final now = DateTime.now().toUtc();
final msgTime = DateTime.parse(envelope['timestamp']);
final window = envelope['window'] ?? 120;
final seq = envelope['seq'];
// Time window check
if (now.difference(msgTime).inSeconds.abs() > window) {
throw Exception('Message expired');
}
// Replay protection
final ledgerKey = '${envelope['senderId']}:$receiverId';
_replayLedger.putIfAbsent(ledgerKey, () => {});
if (_replayLedger[ledgerKey]!.contains(seq)) {
throw Exception('Replay detected');
}
_replayLedger[ledgerKey]!.add(seq);
// Seal check
final expectedSeal = _seal(envelope, key, time);
if (envelope['seal'] != expectedSeal) {
throw Exception('Seal verification failed');
}
// Decrypt
final ct = base64.decode(envelope['ciphertext']);
final pt = _drum(ct, time);
return utf8.decode(pt);
}