cryptdart 0.1.5
cryptdart: ^0.1.5 copied to clipboard
CryptDart is a unified cryptography library for Dart, providing easy-to-use interfaces for symmetric and asymmetric encryption, digital signatures (including ECDSA), and key management. Built on Point [...]
CryptDart #
CryptDart is a comprehensive, unified cryptography library for Dart that provides easy-to-use interfaces for symmetric/asymmetric encryption, digital signatures, key exchange protocols, and secure session management. Built on PointyCastle and BasicUtils with a focus on developer experience and security best practices.
๐ Key Features #
๐ Complete Cryptographic Suite #
- Symmetric Encryption: AES, ChaCha20, DES with multiple modes
- Asymmetric Encryption: RSA with configurable key sizes
- Digital Signatures: HMAC, RSA signatures, ECDSA (EdDSA support planned)
- Key Exchange: ECDH with multiple curves (secp256r1, secp384r1, secp521r1)
๐๏ธ Clean Architecture #
- Three-layer design: Interfaces โ Partial Implementations โ Concrete Classes
- Unified interfaces: Consistent API across all algorithms
- Expiration management: Built-in key and cipher expiration handling
- Centralized utilities: No code duplication, easy maintenance
๐ Secure Session Management #
- Bidirectional ECDH sessions: Automatic key exchange and algorithm negotiation
- Forward secrecy: Ephemeral keys for each session
- Algorithm agility: Dynamic selection of best available algorithms
- Easy integration: High-level factory methods for common use cases
๐งช Production Ready #
- Comprehensive tests: 100+ test cases covering all scenarios
- Strong typing: Full Dart 3.0+ null safety and type safety
- Error handling: Robust error management and validation
- Documentation: Extensive examples and API documentation
๐ฆ Installation #
Add to your pubspec.yaml:
dependencies:
cryptdart: ^0.1.2
Run:
dart pub get
๐ฏ Quick Start #
Basic Symmetric Encryption #
import 'package:cryptdart/cryptdart.dart';
void main() async {
// Generate a secure AES key
final aesKey = AESCipher.generateKey();
print('Generated AES key: ${aesKey.substring(0, 16)}...');
// Create cipher with expiration
final cipher = AESCipher((
parent: (
key: aesKey,
parent: (
parent: (
algorithm: CryptoAlgorithm.aes,
expirationDate: DateTime.now().add(Duration(hours: 24)),
expirationTimes: null,
),
),
),
));
// Encrypt data
final data = 'Hello, secure world! ๐';
final encrypted = cipher.encrypt(data.codeUnits);
final decrypted = cipher.decrypt(encrypted);
print('Original: $data');
print('Decrypted: ${String.fromCharCodes(decrypted)}');
print('Cipher expires: ${cipher.expirationDate}');
}
Asymmetric Encryption & Digital Signatures #
import 'package:cryptdart/cryptdart.dart';
void main() async {
// Generate RSA key pair
final keyPair = await RSACipher.generateKeyPair(bitLength: 2048);
print('Generated RSA ${keyPair['publicKey']!.contains('BEGIN PUBLIC KEY') ? 'โ' : 'โ'}');
// RSA Encryption
final rsaCipher = RSACipher((
parent: (
publicKey: keyPair['publicKey']!,
privateKey: keyPair['privateKey']!,
parent: (
parent: (
algorithm: CryptoAlgorithm.rsa,
expirationDate: DateTime.now().add(Duration(days: 30)),
expirationTimes: null,
),
),
),
));
final message = 'Secret message ๐คซ';
final encrypted = await rsaCipher.encrypt(message.codeUnits);
final decrypted = await rsaCipher.decrypt(encrypted);
print('RSA decrypted: ${String.fromCharCodes(decrypted)}');
// RSA Digital Signature
final signature = RSASignatureCipher((
parent: (
publicKey: keyPair['publicKey']!,
privateKey: keyPair['privateKey']!,
parent: (
parent: (
algorithm: CryptoAlgorithm.rsaSignature,
expirationDate: DateTime.now().add(Duration(days: 30)),
expirationTimes: null,
),
),
),
));
final signData = 'Document to sign';
final sig = await signature.sign(signData.codeUnits);
final verified = await signature.verifySignature(signData.codeUnits, sig);
print('Signature verified: $verified โ');
}
ECDH Key Exchange & Secure Sessions #
import 'package:cryptdart/cryptdart.dart';
import 'dart:convert';
void main() async {
print('๐ Setting up secure ECDH communication...\n');
// High-level secure session establishment
final aliceSession = await SecureCommunicationFactory.initiateSecureSession(
localPeerId: 'alice@example.com',
supportedAsymmetric: [CryptoAlgorithm.rsa],
supportedSymmetric: [CryptoAlgorithm.chacha20, CryptoAlgorithm.aes],
sendToRemote: (initMessage) async {
print('๐ค Alice -> Bob: Session initiation');
// Bob responds to Alice's initiation
final bobResult = await SecureCommunicationFactory.respondToSecureSession(
localPeerId: 'bob@example.com',
initiationMessage: initMessage,
supportedAsymmetric: [CryptoAlgorithm.rsa],
supportedSymmetric: [CryptoAlgorithm.aes, CryptoAlgorithm.chacha20],
);
print('๐ค Bob -> Alice: Session response');
return bobResult.responseMessage;
},
);
print('โ
Secure session established!');
print('๐ Key exchange: ${aliceSession.negotiationResult.keyExchange}');
print('๐ Symmetric cipher: ${aliceSession.negotiationResult.symmetric}');
print('๐ Asymmetric cipher: ${aliceSession.negotiationResult.asymmetric}');
print('๐ Session established: ${aliceSession.establishedAt}');
print('๐ Shared secret length: ${aliceSession.sharedSecret.length} chars\n');
// Test secure communication
final messages = [
'๐ Mission critical data',
'๐ Valuable cryptocurrency keys',
'๐ฅ Medical records - patient #12345',
'๐ Financial transaction: \$50,000 transfer',
];
for (final message in messages) {
final encrypted = aliceSession.encryptData(utf8.encode(message));
final decrypted = aliceSession.decryptData(encrypted);
final result = utf8.decode(decrypted);
print('๐ Encrypted & Decrypted: ${result == message ? 'โ
' : 'โ'} "$message"');
}
}
Low-Level ECDH Key Exchange #
import 'package:cryptdart/cryptdart.dart';
void main() async {
print('๐ Manual ECDH Key Exchange Demo\n');
// Alice generates her ECDH key pair
final aliceKeyPair = await ECDHKeyExchange.generateKeyPair(
curve: ECCKeyUtils.secp256r1,
);
final aliceECDH = ECDHKeyExchange((
parent: (
algorithm: KeyExchangeAlgorithm.ecdh,
expirationDate: DateTime.now().add(Duration(hours: 1)),
expirationTimes: null,
),
publicKey: aliceKeyPair['publicKey']!,
privateKey: aliceKeyPair['privateKey']!,
curve: ECCKeyUtils.secp256r1,
));
// Bob generates his ECDH key pair
final bobKeyPair = await ECDHKeyExchange.generateKeyPair(
curve: ECCKeyUtils.secp256r1,
);
final bobECDH = ECDHKeyExchange((
parent: (
algorithm: KeyExchangeAlgorithm.ecdh,
expirationDate: DateTime.now().add(Duration(hours: 1)),
expirationTimes: null,
),
publicKey: bobKeyPair['publicKey']!,
privateKey: bobKeyPair['privateKey']!,
curve: ECCKeyUtils.secp256r1,
));
print('๐ฉ Alice public key: ${aliceECDH.getPublicKey().substring(0, 50)}...');
print('๐จ Bob public key: ${bobECDH.getPublicKey().substring(0, 50)}...');
// Both parties generate the same shared secret
final aliceSharedSecret = await aliceECDH.generateSharedSecret(
bobECDH.getPublicKey(),
);
final bobSharedSecret = await bobECDH.generateSharedSecret(
aliceECDH.getPublicKey(),
);
print('\n๐ Alice shared secret: ${aliceSharedSecret.substring(0, 20)}...');
print('๐ Bob shared secret: ${bobSharedSecret.substring(0, 20)}...');
print('โ
Secrets match: ${aliceSharedSecret == bobSharedSecret}');
print('๐ Secret length: ${aliceSharedSecret.length} hex characters');
}
๐๏ธ Architecture Overview #
CryptDart follows a clean, three-layer architecture:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Interfaces โ Abstract contracts defining operations
โ ICipher, ISymmetric, IAsymmetric โ
โ ISign, IKeyExchange โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Partial Implementations โ Base classes with shared logic
โ SymmetricCipher, AsymmetricCipher โ
โ CipherBase, SignBase โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Concrete Implementations โ Algorithm-specific implementations
โ AESCipher, RSACipher, HMACSign โ
โ ECDHKeyExchange, ChaCha20Cipher โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Directory Structure #
lib/
โโโ interfaces/ # Abstract contracts
โ โโโ i_cipher.dart # Base cipher interface
โ โโโ i_sign.dart # Signature interface
โ โโโ key_exchange/ # Key exchange interfaces
โโโ implementations/
โ โโโ partial/ # Base classes with shared logic
โ โโโ symmetric/ # AES, ChaCha20, DES implementations
โ โโโ asymmetric/ # RSA implementations
โ โโโ signed_based/ # HMAC, RSA signatures
โ โโโ key_exchange/ # ECDH implementation
โ โโโ session/ # Secure session management
โ โโโ handlers/ # High-level handler classes
โโโ types/ # Enums and type definitions
โโโ utils/ # Centralized utilities (NO duplication!)
๐ง Advanced Usage #
Custom Algorithm Selection #
import 'package:cryptdart/cryptdart.dart';
void main() async {
// Create session with specific algorithm preferences
final customSession = await SecureCommunicationFactory.initiateSecureSession(
localPeerId: 'secure-app-v2.1',
supportedAsymmetric: [CryptoAlgorithm.rsa],
supportedSymmetric: [CryptoAlgorithm.chacha20], // Only ChaCha20
preferredKeyExchange: KeyExchangeAlgorithm.ecdh, // Prefer ECDH
sendToRemote: (message) async {
// Implement your network/IPC communication here
return await sendToRemotePeer(message);
},
);
print('Selected algorithms:');
print(' Key Exchange: ${customSession.negotiationResult.keyExchange}');
print(' Symmetric: ${customSession.negotiationResult.symmetric}');
print(' Asymmetric: ${customSession.negotiationResult.asymmetric}');
}
Future<Map<String, dynamic>> sendToRemotePeer(Map<String, dynamic> message) async {
// Your implementation here
throw UnimplementedError('Implement your communication layer');
}
HMAC Digital Signatures #
import 'package:cryptdart/cryptdart.dart';
void main() async {
// Generate HMAC key
final hmacKey = HMACSign.generateKey();
final hmacSign = HMACSign((
parent: (
key: hmacKey,
parent: (
parent: (
algorithm: CryptoAlgorithm.hmac,
expirationDate: DateTime.now().add(Duration(days: 7)),
expirationTimes: 1000, // Limit to 1000 uses
),
),
),
));
final document = 'Important contract terms and conditions...';
final signature = await hmacSign.sign(document.codeUnits);
final isValid = await hmacSign.verifyHMAC(document.codeUnits, signature);
print('Document signed with HMAC: ${isValid ? 'โ
' : 'โ'}');
print('Remaining uses: ${hmacSign.expirationTimes}');
}
ChaCha20 Stream Cipher #
import 'package:cryptdart/cryptdart.dart';
import 'dart:typed_data';
void main() async {
// Generate ChaCha20 key and nonce
final key = ChaCha20Cipher.generateKey();
final nonce = Uint8List.fromList(List<int>.generate(8, (i) => i * 2));
final cipher = ChaCha20Cipher((
nonce: nonce,
parent: (
key: key,
parent: (
parent: (
algorithm: CryptoAlgorithm.chacha20,
expirationDate: DateTime.now().add(Duration(hours: 2)),
expirationTimes: null,
),
),
),
));
final streamData = List<int>.generate(1024, (i) => i % 256); // 1KB data
final encrypted = cipher.encrypt(streamData);
final decrypted = cipher.decrypt(encrypted);
print('ChaCha20 stream cipher: ${listEquals(streamData, decrypted) ? 'โ
' : 'โ'}');
print('Processed ${streamData.length} bytes');
}
bool listEquals<T>(List<T> a, List<T> b) {
if (a.length != b.length) return false;
for (int i = 0; i < a.length; i++) {
if (a[i] != b[i]) return false;
}
return true;
}
๐งช Testing #
Run the comprehensive test suite:
# Run all tests
dart test
# Run specific test suites
dart test test/ecdh_key_exchange_test.dart # ECDH key exchange tests
dart test test/secure_session_test.dart # Secure session tests
dart test test/symmetric_cipher_test.dart # Symmetric encryption tests
dart test test/asymmetric_cipher_test.dart # Asymmetric encryption tests
dart test test/key_generation_test.dart # Key generation tests
# Run tests with coverage
dart test --coverage=coverage
dart pub global activate coverage
dart pub global run coverage:format_coverage --lcov --in=coverage --out=coverage.lcov --packages=.packages --report-on=lib
Test Coverage #
- โ ECDH Key Exchange: 14 comprehensive tests
- โ Secure Sessions: 3 integration tests
- โ Symmetric Ciphers: AES, ChaCha20, DES encryption/decryption
- โ Asymmetric Ciphers: RSA encryption and signatures
- โ Key Generation: All algorithm key generation tests
- โ Error Handling: Invalid inputs, expiration, format errors
- โ Integration: End-to-end secure communication flows
๐ API Reference #
Core Interfaces #
/// Base cipher interface with expiration support
abstract class ICipher extends IExpiration {
CryptoAlgorithm get algorithm;
List<int> encrypt(List<int> data);
List<int> decrypt(List<int> encryptedData);
}
/// Key exchange protocol interface
abstract class IKeyExchange extends IBaseExpiration {
KeyExchangeAlgorithm get algorithm;
String get publicKey;
Future<String> generateSharedSecret(String otherPublicKey);
}
/// Digital signature interface
abstract class ISign extends IBaseExpiration {
CryptoAlgorithm get algorithm;
Future<List<int>> sign(List<int> data);
Future<bool> verifySignature(List<int> data, List<int> signature);
}
Supported Algorithms #
Symmetric Encryption
- AES: Advanced Encryption Standard (256-bit keys)
- ChaCha20: Modern stream cipher (256-bit keys + 64-bit nonce)
- DES: Data Encryption Standard (192-bit keys, legacy)
Asymmetric Encryption
- RSA: Rivest-Shamir-Adleman (2048, 3072, 4096-bit keys)
Key Exchange
- ECDH: Elliptic Curve Diffie-Hellman
- Curves: secp256r1, secp384r1, secp521r1
Digital Signatures
- HMAC: Hash-based Message Authentication Code
- RSA Signatures: RSA with SHA-256
- ECDSA: Elliptic Curve Digital Signature Algorithm (planned)
๐ก๏ธ Security Best Practices #
1. Key Management #
- โ Generate keys using cryptographically secure random number generators
- โ Use appropriate key sizes (AES-256, RSA-2048+, ECDH-256+)
- โ Implement proper key expiration and rotation policies
- โ Never hardcode keys in source code
2. Session Security #
- โ Use ephemeral keys for forward secrecy
- โ Implement proper algorithm negotiation
- โ Validate all inputs and handle errors securely
- โ Use authenticated encryption when possible
3. Algorithm Selection #
- ๐ฅ Recommended: ChaCha20 + ECDH + RSA signatures
- ๐ฅ Good: AES + ECDH + RSA signatures
- โ ๏ธ Legacy: DES (avoid in new applications)
๐ค Contributing #
We welcome contributions! Please see our Contributing Guidelines for details.
Development Setup #
# Clone the repository
git clone https://github.com/elguala9/CryptDart.git
cd CryptDart
# Install dependencies
dart pub get
# Run tests
dart test
# Run analysis
dart analyze
๐ License #
This project is licensed under the GNU Lesser General Public License v3.0 (LGPL-3.0).
What this means:
- โ You can use CryptDart in commercial applications
- โ You can modify CryptDart for your needs
- โ You can distribute applications using CryptDart
- โน๏ธ If you modify CryptDart itself, you must make those modifications available under LGPL-3.0
- โน๏ธ You must include the LGPL-3.0 license notice
See the LICENSE file for complete details.
๐ Links #
- ๐ API Documentation
- ๐ Issue Tracker
- ๐ฌ Discussions
- ๐ฆ pub.dev Package
Built with โค๏ธ for the Dart & Flutter community
Secure by design, easy by choice. ๐