आप संदेशों को एन्क्रिप्ट करने के लिए ECDiffieHellman का उपयोग कर सकते हैं। आपके पास दो विकल्प हैं: स्टेटिक-स्टेटिक ईसीडीएच और स्थैतिक-क्षणिक ईसीडीएच:
स्थैतिक-स्थिर ईसीडीएच के लिए रिसीवर को प्रेषकों की सार्वजनिक कुंजी (यह आपके आवेदन में एक विकल्प हो सकता है या नहीं) को जानने की आवश्यकता होगी। आपके पास कुछ संदेश भी होना चाहिए जो इस संदेश के लिए अद्वितीय है (यह एक धारावाहिक-संख्या हो सकती है जो आप कहीं और प्रोटोकॉल या डेटाबेस-पंक्ति में प्राप्त करते हैं या जो भी हो या यह एक गैर-हो सकता है)। फिर आप एक गुप्त कुंजी उत्पन्न करने के लिए ईसीडीएच का उपयोग करते हैं और अपने डेटा को एन्क्रिप्ट करने के लिए इसका उपयोग करते हैं। यह आपको 16 बाइट्स की वांछित एन्क्रिप्टेड डेटा लंबाई देगा, लेकिन यह पूरी तरह असममित नहीं है: एन्क्रिप्टर संदेशों को डिक्रिप्ट करने में भी सक्षम है (फिर से: यह आपके एप्लिकेशन में कोई समस्या हो सकती है या नहीं)।
स्टेटिक-इफेमेरल थोड़ा अलग है: यहां एन्क्रिप्टर एक अस्थायी (क्षणिक) ईसी कीपैयर उत्पन्न करता है। उसके बाद वह एक कुंजीपटल उत्पन्न करने के लिए रिसीवर सार्वजनिक कुंजी के साथ इस कीपैयर का उपयोग करता है जिसका उपयोग डेटा एन्क्रिप्ट करने के लिए किया जा सकता है। अंत में वह एन्क्रिप्टेड डेटा के साथ रिसीवर को क्षणिक कीपैयर की सार्वजनिक कुंजी भेजता है। यह आपके एप्लिकेशन में बेहतर फिट हो सकता है, लेकिन पूर्ण एन्क्रिप्टेड डेटा अब ईसीडीएच -256 और एईएस का उपयोग करके 2 * 32 + 16 = 80 बाइट्स होगा (जैसा कि ग्रेग्स नोट्स आप 32 बाइट्स को केवल सार्वजनिक-एक्स के समन्वय को भेजकर सहेज सकते हैं- कुंजी, लेकिन मुझे विश्वास नहीं है कि .NET वाई-समन्वय को पुन: गणना करने के लिए कार्यक्षमता का खुलासा करता है)।
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));
सार्वजनिक कुंजी क्रिप्टोग्राफी बड़ी कुंजी के आकार पर निर्भर करता है, क्योंकि आज तेजी से कंप्यूटर कुछ ही घंटों में भी 256-बिट कुंजी तोड़ सकते हैं:
यहां एक छोटा वर्ग है कि स्थिर स्थैतिक ECDH करना होगा है। यदि सुरक्षा की आवश्यकता अधिक है तो आपको छोटी चाबियों का उपयोग नहीं करना चाहिए। ओडब्ल्यू बस एक सममित कुंजी का उपयोग करें। – apoorv020
@ apoorv020; अंडाकार वक्र सार्वजनिक कुंजी क्रिप्टोग्राफ़ी पर लागू होने पर आपका कथन गलत है। –