Sie können ECDiffieHellman zum Verschlüsseln von Nachrichten verwenden. Sie haben zwei Optionen: Statisch-statisch ECDH und statisch-kurzlebig ECDH:
Für statisch-statische ECDH muss der Empfänger den öffentlichen Schlüssel des Absenders kennen (dies ist in Ihrer Anwendung möglicherweise nicht möglich). Sie sollten auch einige Daten haben, die für diese Nachricht eindeutig sind (es könnte sich um eine Seriennummer handeln, die Sie von einer anderen Stelle in der Protokoll- oder Datenbankzeile oder was auch immer erhalten, oder es könnte eine Nonce sein). Dann verwenden Sie ECDH, um einen geheimen Schlüssel zu generieren und damit Ihre Daten zu verschlüsseln. Dadurch erhalten Sie die gewünschte verschlüsselte Datenlänge von 16 Byte, aber sie ist nicht vollständig asymmetrisch: Der Verschlüssler kann auch die Nachrichten entschlüsseln (wiederum: Dies könnte in Ihrer Anwendung ein Problem darstellen).
Statisch-ephemeral ist ein bisschen anders: Hier generiert der Verschlüssler ein temporäres (ephemeres) EC-Schlüsselpaar. Er verwendet dann dieses Schlüsselpaar zusammen mit dem öffentlichen Schlüssel des Empfängers, um einen geheimen Schlüssel zu erzeugen, der zum Verschlüsseln der Daten verwendet werden kann. Schließlich sendet er den öffentlichen Schlüssel des ephemeren Schlüsselpaares zusammen mit den verschlüsselten Daten an den Empfänger. Dies passt vielleicht besser in Ihre Anwendung, aber die kompletten verschlüsselten Daten sind jetzt 2 * 32 + 16 = 80 Bytes mit ECDH-256 und AES (wie GregS bemerkt, dass Sie 32 Bytes speichern können, indem Sie nur die X-Koordinate der Schlüssel, aber ich glaube nicht, dass .NET die Funktionalität zur Neuberechnung der Y-Koordinate verfügbar macht).
Hier ist eine kleine Klasse, die statische statische ECDH tun:
public static class StaticStaticDiffieHellman
{
private static Aes DeriveKeyAndIv(ECDiffieHellmanCng privateKey, ECDiffieHellmanPublicKey publicKey, byte[] nonce)
{
privateKey.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
privateKey.HashAlgorithm = CngAlgorithm.Sha256;
privateKey.SecretAppend = nonce;
byte[] keyAndIv = privateKey.DeriveKeyMaterial(publicKey);
byte[] key = new byte[16];
Array.Copy(keyAndIv, 0, key, 0, 16);
byte[] iv = new byte[16];
Array.Copy(keyAndIv, 16, iv, 0, 16);
Aes aes = new AesManaged();
aes.Key = key;
aes.IV = iv;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
return aes;
}
public static byte[] Encrypt(ECDiffieHellmanCng privateKey, ECDiffieHellmanPublicKey publicKey, byte[] nonce, byte[] data){
Aes aes = DeriveKeyAndIv(privateKey, publicKey, nonce);
return aes.CreateEncryptor().TransformFinalBlock(data, 0, data.Length);
}
public static byte[] Decrypt(ECDiffieHellmanCng privateKey, ECDiffieHellmanPublicKey publicKey, byte[] nonce, byte[] encryptedData){
Aes aes = DeriveKeyAndIv(privateKey, publicKey, nonce);
return aes.CreateDecryptor().TransformFinalBlock(encryptedData,0, encryptedData.Length);
}
}
// Usage:
ECDiffieHellmanCng key1 = new ECDiffieHellmanCng();
ECDiffieHellmanCng key2 = new ECDiffieHellmanCng();
byte[] data = Encoding.UTF8.GetBytes("TestTestTestTes");
byte[] nonce = Encoding.UTF8.GetBytes("whatever");
byte[] encryptedData = StaticStaticDiffieHellman.Encrypt(key1, key2.PublicKey, nonce, data);
Console.WriteLine(encryptedData.Length); // 16
byte[] decryptedData = StaticStaticDiffieHellman.Decrypt(key2, key1.PublicKey, nonce, encryptedData);
Console.WriteLine(Encoding.UTF8.GetString(decryptedData));
Public-Key-Kryptographie auf große Schlüsselgrößen abhängig, weil heutige schnelle Computer sogar 256-Bit-Schlüssel in ein paar Stunden brechen können. Wenn der Sicherheitsbedarf hoch ist, sollten Sie keine kleinen Schlüssel verwenden. OW verwenden Sie einfach einen symmetrischen Schlüssel. – apoorv020
@apoorv020; Ihre Anweisung ist falsch, wenn sie auf die Kryptografie öffentlicher Schlüssel mit elliptischen Kurven angewendet wird. –