A comprehensive end-to-end encryption (E2EE) library for .NET, providing secure cryptographic operations including symmetric/asymmetric encryption, key exchange, digital signatures, and secure key management.
-
Symmetric Encryption
- AES-GCM (Galois/Counter Mode) - Authenticated encryption
- AES-CBC (Cipher Block Chaining) with optional HMAC authentication
- Support for 128, 192, and 256-bit keys
-
Asymmetric Encryption
- RSA encryption with OAEP padding
- Support for 2048, 3072, and 4096-bit keys
- Hybrid encryption (RSA + AES-GCM)
-
Key Exchange
- ECDH (Elliptic Curve Diffie-Hellman)
- Support for P-256, P-384, and P-521 curves
-
Digital Signatures
- RSA signatures with PSS or PKCS#1 v1.5 padding
- ECDSA (Elliptic Curve Digital Signature Algorithm)
-
Key Derivation
- PBKDF2 (Password-Based Key Derivation Function 2)
- HKDF (HMAC-based Key Derivation Function)
-
Secure Key Storage
- In-memory key storage with secure clearing
- Extensible interface for custom storage backends
-
Signal Protocol-like Secure Messaging
- X3DH (Extended Triple Diffie-Hellman) key agreement
- Double Ratchet algorithm for forward-secure messaging
- Pre-key bundles for asynchronous session establishment
- Header Encryption: Protects message metadata (ratchet keys, counters)
- Sender Keys Protocol: Efficient group messaging with
GroupSession - Forward Secrecy: Past messages remain secure if keys are compromised
- Post-Compromise Security: Future messages become secure after compromise
- Extensibility:
ICurve25519andIEdDSAinterfaces for custom cryptographic providers
| Platform | Version |
|---|---|
| .NET Standard | 2.0, 2.1 |
| .NET Framework | 4.8, 4.8.1 |
| .NET | 6.0, 7.0, 8.0, 9.0, 10.0 |
Note: Full functionality (RSA, ECDSA, ECDH, hybrid encryption) requires .NET Core 3.0+ or .NET 5.0+. Signal Protocol features (SecureMessaging, X3DH, Double Ratchet) require .NET 6.0+. On .NET Framework 4.8/4.8.1 and .NET Standard 2.0/2.1, only symmetric encryption (AES-GCM, AES-CBC), key derivation (PBKDF2, HKDF), and utility functions are available.
dotnet add package LucindaOr via NuGet Package Manager:
Install-Package LucindaThe EndToEndEncryption class provides a simplified API for common E2EE scenarios:
using Lucinda; // Create an E2EE instance using var e2ee = new EndToEndEncryption(); // Generate key pairs for Alice and Bob var aliceKeyPair = e2ee.GenerateKeyPair(); var bobKeyPair = e2ee.GenerateKeyPair(); // Alice encrypts a message for Bob var encrypted = e2ee.EncryptMessage("Hello, Bob!", bobKeyPair.Value.PublicKey); // Bob decrypts the message var decrypted = e2ee.DecryptMessage(encrypted.Value, bobKeyPair.Value.PrivateKey); Console.WriteLine(decrypted.Value); // "Hello, Bob!"The SecureMessaging class provides Signal Protocol-like security with X3DH and Double Ratchet:
using Lucinda; // Alice and Bob setup using var alice = new SecureMessaging(); using var bob = new SecureMessaging(); alice.GenerateIdentityKeyPair(); bob.GenerateIdentityKeyPair(); bob.GeneratePreKeyBundle(); // Alice initiates session with Bob's pre-key bundle var bobBundle = bob.GetPublicPreKeyBundle(); alice.InitializeSession("bob", bobBundle.Value); // Bob creates session from Alice's initial contact var initialMessage = alice.GetInitialMessageData("bob"); bob.CreateSessionFromInitialMessage("alice", initialMessage.Value); // Send encrypted messages with forward secrecy var encrypted = alice.SendMessage("bob", "Hello with forward secrecy!"); var decrypted = bob.ReceiveMessage("alice", encrypted.Value); Console.WriteLine(decrypted.Value); // "Hello with forward secrecy!"using Lucinda.Protocol.SenderKeys; // Create group sessions for each participant using var alice = new GroupSession("my-group-123", "alice"); using var bob = new GroupSession("my-group-123", "bob"); using var charlie = new GroupSession("my-group-123", "charlie"); // Initialize sender keys alice.Initialize(); bob.Initialize(); charlie.Initialize(); // Exchange distribution messages (each participant shares their sender key) var aliceDist = alice.CreateDistributionMessage(); var bobDist = bob.CreateDistributionMessage(); alice.ProcessDistributionMessage("bob", bobDist.Value); bob.ProcessDistributionMessage("alice", aliceDist.Value); // Alice sends encrypted message to the group (single encryption for all recipients) var groupMessage = alice.Encrypt(Encoding.UTF8.GetBytes("Hello group!")); // Bob decrypts the group message var decrypted = bob.Decrypt(groupMessage.Value); Console.WriteLine(Encoding.UTF8.GetString(decrypted.Value)); // "Hello group!"using Lucinda.Symmetric; // Generate a new key using var aes = new AesGcmEncryption(256); // 256-bit key // Encrypt data var plaintext = "Sensitive data"u8.ToArray(); var encrypted = aes.Encrypt(plaintext); // Decrypt data var decrypted = aes.Decrypt(encrypted.Value); // With associated data (AAD) var metadata = "header"u8.ToArray(); var encryptedWithAad = aes.Encrypt(plaintext, metadata); var decryptedWithAad = aes.Decrypt(encryptedWithAad.Value, metadata);using Lucinda.Asymmetric; using var hybrid = new RsaAesHybridEncryption(); // Generate a key pair var keyPair = hybrid.GenerateKeyPair(); // Encrypt (anyone with the public key can encrypt) var data = "Large amount of data..."u8.ToArray(); var encrypted = hybrid.Encrypt(data, keyPair.Value.PublicKey); // Decrypt (only the private key holder can decrypt) var decrypted = hybrid.Decrypt(encrypted.Value, keyPair.Value.PrivateKey);using Lucinda.Signatures; // ECDSA signatures using var signer = new EcdsaSignature(); var keyPair = signer.GenerateKeyPair(); var data = "Data to sign"u8.ToArray(); // Sign var signature = signer.Sign(data); // Verify var isValid = signer.Verify(data, signature.Value); Console.WriteLine(isValid.Value); // trueusing Lucinda.KeyDerivation; using var pbkdf2 = new Pbkdf2KeyDerivation(); // Derive a key from a password var password = "MySecretPassword"; var salt = SecureRandom.GenerateSalt(32); var derivedKey = pbkdf2.DeriveKey(password, salt, iterations: 600000, derivedKeyLength: 32); // Use derivedKey.Value for encryptionusing Lucinda.KeyDerivation; using var hkdf = new HkdfKeyDerivation(); // Derive keys from a shared secret var sharedSecret = new byte[32]; // From key exchange var salt = SecureRandom.GenerateSalt(32); var info = "encryption-key"u8.ToArray(); var encryptionKey = hkdf.DeriveKey(sharedSecret, salt, info, 32);using Lucinda.KeyExchange; // Alice generates her key pair using var aliceEcdh = new EcdhKeyExchange(); var alicePublicKey = aliceEcdh.GetPublicKey(); // Bob generates his key pair using var bobEcdh = new EcdhKeyExchange(); var bobPublicKey = bobEcdh.GetPublicKey(); // Both derive the same shared secret var aliceSharedSecret = aliceEcdh.DeriveSharedSecret(bobPublicKey.Value); var bobSharedSecret = bobEcdh.DeriveSharedSecret(alicePublicKey.Value); // aliceSharedSecret == bobSharedSecretusing Lucinda; using var e2ee = new EndToEndEncryption(); // Generate keys var senderSigningKeyPair = e2ee.GenerateSigningKeyPair(); var recipientKeyPair = e2ee.GenerateKeyPair(); var message = "Authenticated and encrypted message"u8.ToArray(); // Encrypt and sign var signedEncrypted = e2ee.EncryptAndSign( message, recipientKeyPair.Value.PublicKey, senderSigningKeyPair.Value.PrivateKey); // Verify and decrypt var decrypted = e2ee.VerifyAndDecrypt( signedEncrypted.Value, recipientKeyPair.Value.PrivateKey, senderSigningKeyPair.Value.PublicKey); if (decrypted.IsSuccess) { Console.WriteLine("Message verified and decrypted!"); }All cryptographic operations return a CryptoResult<T> that encapsulates success or failure:
var result = aes.Encrypt(data); if (result.IsSuccess) { var encrypted = result.Value; // Use encrypted data } else { Console.WriteLine($"Error: {result.Error}"); } // Or use pattern matching result.Match( onSuccess: data => ProcessData(data), onFailure: error => HandleError(error) );- Key Management: Always securely store and protect private keys.
- Random Number Generation: The library uses
System.Security.Cryptography.RandomNumberGeneratorfor cryptographically secure random numbers. - Memory Security: Sensitive data (keys, plaintext) is cleared from memory when possible.
- Authenticated Encryption: Use AES-GCM or enable HMAC with AES-CBC to ensure data integrity.
- Key Sizes: Use at least 2048-bit RSA keys and 256-bit AES keys for production.
- Password Hashing: Use PBKDF2 with at least 600,000 iterations for password-based key derivation.
| Class | Description |
|---|---|
EndToEndEncryption | High-level E2EE operations |
AesGcmEncryption | AES-GCM authenticated encryption |
AesCbcEncryption | AES-CBC encryption |
RsaEncryption | RSA asymmetric encryption |
RsaAesHybridEncryption | Hybrid RSA+AES encryption |
EcdhKeyExchange | ECDH key exchange |
RsaSignature | RSA digital signatures |
EcdsaSignature | ECDSA digital signatures |
Pbkdf2KeyDerivation | Password-based key derivation |
HkdfKeyDerivation | HKDF key derivation |
InMemoryKeyStorage | Secure in-memory key storage |
SecureMessaging | Signal Protocol-like secure messaging |
X3DHKeyAgreement | X3DH key agreement protocol |
DoubleRatchet | Double Ratchet algorithm |
HeaderEncryption | Header encryption for metadata protection |
GroupSession | Sender Keys protocol for group messaging |
| Interface | Description |
|---|---|
ISymmetricEncryption | Contract for symmetric encryption |
IAsymmetricEncryption | Contract for asymmetric encryption |
IHybridEncryption | Contract for hybrid encryption |
IKeyExchange | Contract for key exchange |
IDigitalSignature | Contract for digital signatures |
IKeyDerivation | Contract for key derivation |
ISecureKeyStorage | Contract for secure key storage |
IX3DHKeyAgreement | Contract for X3DH key agreement |
IDoubleRatchet | Contract for Double Ratchet |
IKdfChain | Contract for KDF chain operations |
ISessionStorage | Contract for session storage |
IHeaderEncryption | Contract for header encryption |
IGroupSession | Contract for group messaging sessions |
ICurve25519 | Contract for X25519 key exchange (extensibility) |
IEdDSA | Contract for Ed25519 signatures (extensibility) |
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
- Built on .NET's
System.Security.Cryptographynamespace - Follows modern cryptographic best practices