您可以使用ECDiffieHellman来加密邮件。您有两种选择:静态ECDH和静态短暂ECDH:对于静态静态ECDH,接收方需要知道发送方公钥(这可能是也可能不是您的应用中的选项)。您还应该拥有一些对此消息唯一的数据(它可能是您从协议或数据库中的其他位置获得的序列号 - 行或其他内容,或者它可能是随机数)。然后您使用ECDH生成一个密钥并使用它来加密您的数据。这会给你所需的加密数据长度为16个字节,但它不是完全不对称的:加密器也能够解密这些消息(再次说明:这可能是或者可能不是你的应用程序中的问题)。
Static-ephemeral有点不同:这里的加密器会生成一个临时(临时)EC密钥对。然后他将这个密钥对与接收者公钥一起使用来生成可用于加密数据的密钥。最后他将短暂密钥对的公钥与加密数据一起发送给接收方。这可能更适合您的应用程序,但使用ECDH-256和AES,现在完整的加密数据现在将为2 * 32 + 16 = 80个字节(正如GregS指出,您只需发送公共的x坐标即可节省32个字节,关键,但我不相信.NET公开了重新计算y坐标的功能)。
这里是一个小班,会做静态静态ECDH:
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位密钥。如果安全需求很高,那么你不应该使用小键盘。 OW只是使用对称密钥。 – apoorv020 2010-07-07 16:11:50
@ apoorv020;您的声明在应用于椭圆曲线公钥加密时是不正确的。 – 2010-07-07 23:13:08